我是一名Haskell新手,试图将我的头转向函数中的类型绑定(bind)以及Haskell如何执行它。例如,即使fst
函数的类型为fst :: (a, b) -> a
,编译器也不会抱怨函数fst'
。但是编译器抱怨函数elem'
的类型绑定(bind)。
fst' :: (a,a) -> a
fst' s = fst s
elem' :: (Eq a, Eq b) => a -> [b] -> Bool
elem' x xs = elem x xs
最佳答案
fst
具有 fst :: (a, b) -> a
类型,这意味着可以定义一个函数:
fst' :: (a, a) -> a
fst' = fst
您的
fst'
函数比fst
函数更具限制性。无论用什么替换a
函数中的fst'
都适合fst
。例如,如果a ~ Bool
成立,那么您将使用签名fst
调用fst :: (Bool, Bool) -> Bool
。但是因为fst
可以处理所有a
和b
,所以元组的两个元素都是Bool
很好,因此给定的fst
可以处理2元组的第一和第二项所有可能类型的元组。如果这两个项目具有相同的类型,肯定可以。后者不行,请在此处定义:
elem' :: (Eq a, Eq b) => a -> [b] -> Bool
elem' = elem
但
elem
的类型为 elem :: Eq a => a -> [a] -> Bool
。由于可以设置elem'
和elem
,因此可以使用a ~ Int
函数创建的签名不是b ~ Bool
函数的签名的子集。在那种情况下,您期望elem :: Int -> [Bool] -> Bool
,但显然不成立,因为Int
和Bool
类型是两种不同的类型,并且在elem
签名中,它们都是a
。关于haskell - Haskell何时会提示函数输入错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57242142/