문제

Consider:

:type (flip .)

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

I just can't figure out why. As I understand, flip has the following type:

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

In addition (.) has the following type:

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

Hence, unifying the types I get:

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

Which gives:

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

Which is far from the actual type.

What am I doing wrong? Any sort of help would be appreciated.

도움이 되었습니까?

해결책

Consider the type of flip and function composition:

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

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

Now you can either apply (.) to flip or else apply flip to (.).

In the first case:

(flip .)

-- is the same as

(.) flip

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

Hence you get:

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

In the second case:

(flip (.))

-- is the same as

flip (.)

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

Hence you get:

(.) :: (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

The problem is that when you write (flip .) Haskell assumes that it is a section. Hence it considers flip as an argument since . is an operator. To treat an operator as a function you need to parenthesize it. Hence (flip (.)) is treated as applying flip to (.). In this case the extra set of parentheses are not required. You can simply write it as flip (.).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top