我是一名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可以处理所有ab,所以元组的两个元素都是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,但显然不成立,因为IntBool类型是两种不同的类型,并且在elem签名中,它们都是a

关于haskell - Haskell何时会提示函数输入错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57242142/

10-10 18:08