haskell - Why does the following typecheck? -
why following typecheck?
cancel x y = x distribute f g x = f x (g x) identity = distribute cancel cancel clearly cancel :: -> b -> a, distribute :: (a -> b -> c) -> (a -> b) -> -> c , identity :: -> a. now, distribute cancel :: (a -> b) -> -> a, don't understand why cancel matches a -> b.
could explain me?
let's make type variables distinct:
identity = distribute cancel1 cancel2 distribute :: (a -> b -> c) -> (a -> b) -> -> c cancel1 :: x -> y -> x cancel2 :: r -> s -> r so, lining types need unify prove distribute call checks out:
distribute :: (a -> b -> c) -> (a -> b) -> -> c cancel1 :: x -> y -> x cancel2 :: r -> s -> r cancel1 obvious; have:
a ~ x b ~ y c ~ x (the ~ sign how write equality of types in haskell; can use in actual code if turn on extensions)
let's substitute in
distribute :: (x -> y -> x) -> (x -> y) -> x -> x cancel1 :: x -> y -> x cancel2 :: r -> s -> r for next bit, need remember arrow is binary operator. takes 2 parameters: argument type , result type.so if we've got function type 2 arrows 1 of them must inside argument type or result type of other. in case r -> s -> r, we're using right associativity of -> leave out parentheses make obvious: it's r -> (s -> r).1
so then:
distribute :: (x -> y -> x) -> (x -> y ) -> x -> x cancel1 :: x -> y -> x cancel2 :: r -> (s -> r) so can read off:
x ~ r y ~ s -> r more substitution:
distribute :: (r -> (s -> r) -> r) -> (r -> (s -> r)) -> r -> r cancel1 :: r -> (s -> r) -> r cancel2 :: r -> (s -> r) so thing cancel1 ignoring function of type s -> r, cancel2 returns. remembering f x (g x) implementation of distribute, makes sense. cancel1 , cancel2 both have called same thing; cancel1 receives result of calling cancel2 second argument, promptly ignores, doesn't matter type of cancel2's second parameter it's never called on argument (any function @ accepts r first parameter have worked here). elaborate way write function nothing: identity.
1 if have trouble remembering whether -> right or left associative, may have heard haskell functions take single argument , commonly "fake" multiple-argument functions using functions return other functions. that's what's going on here, , why function arrow associates right.
Comments
Post a Comment