我在Haskell中编写了一个函数,它应该接受一个列表以及列表的大小; 它应该创建一个具有给定大小的Data.Vector.Mutable.MVector,用列表的内容填充向量并返回此向量。
TL;DR
大部分我写的时候并没有真正理解它们的作用(最后一行),因此,我无法想出一个合适的类型签名。然而,编译器出手拯救了这个局面,生成了以下类型签名:
很明显,到这一步为止,这个看起来有些简单的类型签名似乎与我想要函数执行的内容完全相同,但实际上是不正确的。为了得出这个类型签名,我使用了向量模块中一些我认为类似的其他函数的类型签名,比如这个:
- 我想知道为什么我提供的类型签名不起作用。我从这个签名中漏掉了什么,使它不能被接受为类型签名?
- 是否可能创建一个函数,同时使用我的类型签名来执行上述操作?
- 如何解释编译器根据我编写的代码生成的类型签名?
vecFromList lst sz = MV.new sz >>= (\vec -> fillV (zip [0..sz - 1] lst) vec) where
fillV [] vec = vec
fillV ((i, v):xs) vec = MV.write vec i v >> fillV xs vec
大部分我写的时候并没有真正理解它们的作用(最后一行),因此,我无法想出一个合适的类型签名。然而,编译器出手拯救了这个局面,生成了以下类型签名:
vecFromList
:: (PrimMonad (MVector t), PrimState (MVector t) ~ t) =>
[b] -> Int -> MVector t b
我听到有人说“Wat?”,哦,那是我自言自语。无论如何... 在我尝试编译之前,这是我认为应该有效的类型签名:
我认为应该有效的类型签名
vecFromList :: PrimMonad m => [t] -> Int -> MV.MVector (PrimState m) t
很明显,到这一步为止,这个看起来有些简单的类型签名似乎与我想要函数执行的内容完全相同,但实际上是不正确的。为了得出这个类型签名,我使用了向量模块中一些我认为类似的其他函数的类型签名,比如这个:
Data.Vector.Mutable.read
:: PrimMonad m => MVector (PrimState m) a -> Int -> m a
现在,我对Haskell还比较陌生,仍在努力适应语言中使用的符号和标志,特别是试图理解为什么看起来很简单的任务由于Monads而变得如此复杂。例如,MVector
具有这种类型MVector :: * -> * -> *:
的目的是什么?
forM_
而不是for_
?谢谢。 - smac89for_
和forM_
本质上是相同的,for_
只有一个更弱的 (Applicative
) 约束。 - cchalmers