为什么不能定义运算符:=在GHC中?在将来的版本中可以消除这种限制吗?
这是输出:
[1 of 1] Compiling Images ( Images.hs, interpreted )
Images.hs:19:1:
Invalid type signature: (:=) :: HasSetter s => s a -> a -> IO ()
Should be of form <variable> :: <type>
Run Code Online (Sandbox Code Playgroud)
构造函数使用旧数据创建新数据类型.让我们推出自己的清单:
data List a = Empty | Cons a (List a)
myList = Const 1 (Cons 2 Empty) -- 1:2:[] =[1,2]
uncons x' (Cons x xs) = if x == x' then xs else Cons x xs
Run Code Online (Sandbox Code Playgroud)
这Cons :: a -> List a是一个特殊的函数,它接受一个元素和一个列表并生成一个更长的列表.
重要的是构造函数和普通函数之间存在差异,以便编译器知道模式匹配中哪一个有效:
headM (Cons x xs) = Just x
headM Empty = Nothing
Run Code Online (Sandbox Code Playgroud)
这是有道理的,但这不是:
previousHead (uncons x xs) = Just x
previousHead xs = Nothing
Run Code Online (Sandbox Code Playgroud)
因为计算机如何知道您删除了哪个元素或者是否删除了哪个元素?
有时候,与列表一样,有一个构造函数工作中缀是有帮助的,所以我们实际上有相应的
data [a] = [] | a:[a]
Run Code Online (Sandbox Code Playgroud)
所以我们可以写出像1:2:[].
中缀函数需要与标识符分开,因此我们可以x:xs毫不含糊地写出没有空格,因此中缀函数(包括中缀构造函数:必须完全由符号而不是字母组成).
编译器仍然需要能够在构造函数为中缀时将它们与普通函数区分开来,因此我们需要等效于构造函数以大写字母开头的规则.语言设计者指定:为唯一的大写符号,因此中缀构造函数必须从它开始,而普通函数则不能.
您可以将其:=用作构造函数,以便进行定义
data Assignment a = Variable := Expression a
Run Code Online (Sandbox Code Playgroud)
但是如果你想调用一个普通的函数:=,你就不能,因为:它不能在前面被认为是大写符号,你必须从别的东西开始,因为(简单但没有意义)的例子:
(.:=) :: Maybe a -> a -> Maybe a
Nothing .:= x = Just x
Just y .:= x = Just x
Run Code Online (Sandbox Code Playgroud)