我正在学习Haskell,但我发现很难理解什么似乎是最基本的东西!首先,了解类型。 例如,我真的不了解这些函数的类型,
threetimes f x = f (f (f x))
或
triple x = x * 3
不会将三倍x和三倍为整数类型,因为它们采用值并对它们应用操作?
另外,在查看最后一个函数时,
last xs = head (reverse xs)
最后一种类型是什么?
谢谢你们。对不起,如果这个问题看起来很基本!
答案 0 :(得分:11)
您可以通过查看类型的应用方式和使用的函数来构建类型。
threetimes
以例如:
threetimes f x = f (f (f x))
我们首先假设f
的类型为a
(f :: 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
,因此我们知道b
和c
属于同一类型b ~ c
,f :: b -> b
和f (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
我们可以再次查看head
和reverse
:
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