我有以下类型的签名:
*Main Lib> let f :: a -> a -> a -> a; f = undefined
*Main Lib> let x :: Char; x = undefined
为了找出我会得到哪种结果类型,我做了:
*Main Lib> :t f x
f x :: Char -> Char -> Char
好呀
Char -> Char -> Char -> Char
因为第一个参数已经被x
替换了吗?
发布于 2017-02-21 10:24:08
是的,完全正确。考虑一个不同的函数,length :: [a] -> Int
。如果您要求类型的length "abc"
,您将得到Int
Prelude> :t length "foo"
length "foo" :: Int
通常,如果您有一个函数f :: A -> B
和一个参数x :: A
,那么f x :: B
。
在您的例子中,我们有f :: a -> (a -> a -> a)
(专门用于a = Char
),因此A = Char
和B = Char -> Char -> Char
。
(a -> a -> a -> a
与a -> (a -> a -> a)
相同,因为类型中的->
是正确的关联。)
发布于 2017-02-21 10:21:20
这是因为f x
是函数f
,它的第一个参数已经被应用了,所以它只需要另外两个就可以得到结果。这就是所谓的赛跑。
在Haskell中,没有像函数这样有三个参数的东西。a -> a -> a -> a
的意思是“接受a
的函数,返回接受a
的函数,返回接受a
并返回a
的函数”。
这是一个很大的口才写出来,所以只要加入一些家长,它会变得更清楚:a -> (a -> (a -> a))
。
所以f x
给了你a -> (a -> a)
。恰巧Haskell的语法允许你说f x y z
,就像你在用三个参数调用一个函数一样,编译器很聪明,在不需要的时候就不会构造所有中间的咖喱函数。
https://stackoverflow.com/questions/42364529
复制相似问题