我在任何地方看到并使用::
符号,但在Haskell编程时仍然不知道::
符号的含义,例如。
run :: Int -> Int -> Int
-- ??
Haskell中::
(双冒号)代表什么?
答案 0 :(得分:37)
你可以谷歌搜索haskell "double colon"
或类似的东西;不幸的是谷歌的语法有点难,但在这种情况下你可以命名。
在Haskell中,没有它你的程序通常运行正常(虽然你会想用它来磨练你定义的任何函数的规范,这是一个好习惯)。
这个想法是你可以在任何地方(甚至在表达式的中间)插入一个:: ...
来说“按照Compiler先生的方式,这个表达式应该是...
类型”。如果可以证明这可能不是这种情况,编译器将抛出错误。
我认为您也可以使用它来“转换”函数到您想要的版本;例如如果一个函数是“多态的”(具有一般类型签名)并且你真的想要一个Integer
,那么你可以对结果值做:: Integer
;我虽然有点生疏。
答案 1 :(得分:12)
你应该阅读:
foo :: a
“名称foo
是a
类型的值”。当你写:
run :: a -> b
这意味着:
您要声明名称run
。
此名称将引用类型为a -> b
,
类型a -> b
是函数的类型,它采用类型a
的值并返回类型b
的另一个值。
你必须真正了解了解Haskell的类型。类型系统是Haskell最重要的特性之一,它是使语言如此富有表现力的原因。
答案 2 :(得分:6)
当你有一个看起来很可怕的类型检查错误时,你可以(暂时)将部分代码包装在(myexpression :: MyType)
中,以明确地向编译器说明你期望myexpression
具有哪种类型。这通常有助于编译器为您提供更好的错误消息。
答案 3 :(得分:0)
多年后,我遇到了这个问题,我想我会指出这里有一个微妙之处。 ::
确实表示某种类型的东西。但它也用于描述某事物的 kind
:
ghci> :type []
[] :: [a]
ghci> :kind []
[] :: * -> *
类型和种类是相关但不同的东西。
我从 Hackage 中的以下内容中注意到这一点:
class Applicative m => Monad (m :: Type -> Type) where
...
而 Type -> Type
是 * -> *
的长形式。
我认为阅读上述内容的方式是“对于某些类型'm',其中m具有种类* -> *
,Monad m
扩展Applicative m
并且需要实现......”