简体   繁体   English

Haskell 的类型签名

[英]type signature of Haskell

cow :: (Eq a) => a -> a -> [a] -> Bool
cow x y z = x && y `elem` z

 foo ::
 foo x y z = x `elem` y && y `elem` z

 bar::
 bar x y = case y of
    Nothing -> x
    Just z  -> x + z

I don't know what the type signature should be.我不知道类型签名应该是什么。

In order to determine the type signatures.为了确定类型签名。 You do not need to know what a function is doing.您不需要知道function 在做什么。 You can use the type signatures of the functions you use, and do inference on that.您可以使用您使用的函数的类型签名,并对其进行推断。

Since the type signature of your cow function is not entirely correct, we will show how to derive the type signature of the cow function, and then leave the two others as exercises.由于你的cow function 的类型签名并不完全正确,我们将展示如何推导出cow function 的类型签名,然后将其他两个留作练习。

We see that cow here has three parameters: x , y and z .我们看到这里的cow有三个参数: xyz At the moment, we do not know much about x , y and z .目前,我们对xyz So we will assign a different type variable for these variables.所以我们将为这些变量分配一个不同的类型变量。 So x:: a , y:: b and z:: c .所以x:: ay:: bz:: c

Next we can start to derive the types.接下来我们可以开始推导类型。 The function definition of cow : cow的 function 定义:

cow x y z = x && y `elem` z

can be written in a more canonical format as:可以写成更规范的格式:

cow x y z = (&&) x (elem y z)

We thus see that we make use of two functions here: (&&):: Bool -> Bool -> Bool , andelem:: (Eq e, Foldable f) => e -> fe -> Bool , we here use e instead of f to avoid "name clashes" with our already defined type variable a .因此,我们看到我们在这里使用了两个函数: (&&):: Bool -> Bool -> Boolelem:: (Eq e, Foldable f) => e -> fe -> Bool ,我们在这里使用e而不是f以避免与我们已经定义的类型变量a发生“名称冲突”。 Since we use x as argument of the (&&):: Bool -> Bool -> Bool function, we know that x should have type Bool , and thus that a ~ Bool ( a is the same type as Bool ).由于我们使用x作为(&&):: Bool -> Bool -> Bool function 的参数,我们知道x应该具有Bool类型,因此a ~ BoolaBool类型相同)。 Furthermore we thus know that (&&) x:: Bool -> Bool .此外,我们因此知道(&&) x:: Bool -> Bool

Next we see that we call elem:: (Eq e, Foldable f) => e -> fe -> Bool .接下来我们看到我们调用elem:: (Eq e, Foldable f) => e -> fe -> Bool This thus means that y , which is the first parameter applied to elem thus has type e , and therefore b ~ e .因此,这意味着y ,它是应用于elem的第一个参数,因此具有类型e ,因此具有b ~ e

It furthermore means that elem x thus has type (Eq e, Foldable f) => fe -> Bool , and we apply this function to the z parameter.这进一步意味着elem x因此具有类型(Eq e, Foldable f) => fe -> Bool ,我们将此 function 应用于z参数。 This thus means that c ~ (Eq e, Foldable f) => fe , and that the type of elem yz is Bool .因此,这意味着c ~ (Eq e, Foldable f) => fe ,并且elem yz的类型是Bool

Since the type of elem yz is Bool , this matches with the function (&&) x , and thus the type of (&&) x (elem yz) is thus Bool .由于elem yz的类型是Bool ,这与 function (&&) x匹配,因此(&&) x (elem yz)的类型是Bool

We thus have derived that:因此,我们得出:

x :: Bool
y :: e
z :: f e

with as type constraints Eq e and Foldable f .具有类型约束Eq eFoldable f This thus means that cow has as function:因此,这意味着cow具有 function:

cow :: (Eq e, Foldable f) => Bool -> e -> f e -> Bool
cow x y z = x && y `elem` z

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM