无法弄清楚为什么(翻转。)有这种类型

时间:2014-05-13 01:46:11

标签: haskell haskell-platform

考虑:

:type (flip .)

(flip .) :: (a -> a1 -> b -> c) -> a -> b -> a1 -> c

我无法弄清楚原因。据我了解,flip具有以下类型:

flip :: (a -> b -> c) -> b -> a -> c

此外,(.)具有以下类型:

(.) :: (b1 -> c1) -> (a1 -> b1) -> a1 -> c1

因此,统一我得到的类型:

a = (b1 -> c1) -> (a1 -> b1)
b = a1

给出了:

(flip .) :: a1 -> ((b1 -> c1) -> (a1 -> b1)) -> c1

这与实际类型相差无几。

我做错了什么?任何形式的帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

考虑flip的类型和函数组成:

flip :: (a -> b -> c) -> b -> a -> c

(.) :: (b -> c) -> (a -> b) -> a -> c

现在,您可以将(.)应用于flip,也可以将flip应用于(.)

在第一种情况下:

(flip .)

-- is the same as

(.) flip

-- i.e. you are applying (.) to flip

因此你得到:

flip :: (a -> b -> c) -> b -> a -> c
        |___________|   |___________|
              |               |
(.) ::        b               c       -> (a -> b) -> a -> c

-- Hence:

(flip .) :: (a -> a1 -> b -> c) -> a -> b -> a1 -> c

(.) flip :: (a -> a1 -> b -> c) -> a -> b -> a1 -> c

在第二种情况下:

(flip (.))

-- is the same as

flip (.)

-- i.e. you are applying flip to (.)

因此你得到:

(.) :: (b -> c) -> (a -> b) -> a -> c
       |______|    |______|   |______|
          |           |          |
flip ::   a           b          c     -> b -> a -> c

-- Hence:

(flip (.)) :: (a -> b) -> (b -> c) -> a -> c

flip (.) :: (a -> b) -> (b -> c) -> a -> c

问题在于,当你写(flip .)时,Haskell认为它是一个部分。因此,它将flip视为参数,因为.是一个运算符。要将运算符视为函数,您需要将其括起来。因此,(flip (.))被视为将flip应用于(.)。在这种情况下,不需要额外的括号集。您只需将其写为flip (.)