你会如何在Haskell中定义这些类型?

时间:2018-02-03 20:14:05

标签: function haskell types

我正在学习Haskell,但我发现很难理解什么似乎是最基本的东西!首先,了解类型。 例如,我真的不了解这些函数的类型,

threetimes f x = f (f (f x))

triple x = x * 3

不会将三倍x和三倍为整数类型,因为它们采用值并对它们应用操作?

另外,在查看最后一个函数时,

last xs = head (reverse xs)

最后一种类型是什么?

谢谢你们。对不起,如果这个问题看起来很基本!

1 个答案:

答案 0 :(得分:11)

您可以通过查看类型的应用方式和使用的函数来构建类型。

threetimes

以例如:

threetimes f x = f (f (f x))

我们首先假设f的类型为af :: a},x的类型为b(所以x :: b )。

现在我们来看看函数的主体,最内层的表达式是f x,这意味着f是一个函数,它需要x作为输入,所以它是一个函数f :: b -> c。因此f x的类型为f x :: c。但现在我们查看f (f x),因为f x :: c,因此意味着f的输入类型应为c,但我们已将其设置为b ,因此我们知道bc属于同一类型b ~ cf :: b -> bf (f x) :: b

然后我们看一下整个表达式f (f (f x))。这意味着类型为b,因此我们得出结论:

threetimes :: (b -> b) -> b -> b

triple

对于triple x,我们来看看:

triple x = x * 3

操作符实际上是一种编写函数的便捷方式,我们实际写道:

triple x = (*) x 3

如果我们查看(*)函数以及3字面值,我们会看到:

(*) :: Num a => a -> a -> a
3 :: Num b => b

这意味着我们知道x属于a类型(即x :: Num a => a),因此我们将Num a => a -> a应用于3 },这意味着a ~ b,因此结果类型为:

triple :: Num a => a -> a

last

我们可以再次查看headreverse

reverse :: [a] -> [a]
head :: [b] -> b

所以,如果我们现在分析:

last xs = head (reverse xs)

这意味着我们以reverse作为参数调用xs,因此我们知道xs :: [a]reverse xs :: [a],然后我们调用head(reverse xs)为参数,现在我们知道[a] ~ [b],结果a ~ b。我们也可以得出结论head (reverse xs) :: a,所以这意味着:

last :: [a] -> a