user124659
user124659

Reputation: 15

Confuse about flip function

charIn ::  Char -> String -> Bool
charIn _ []       = False
charIn x (y:ys)   = x==y || charIn x ys

isWord :: String -> Bool
isWord = all $ flip charIn "abcdefghijklmnopqrstuvwxyz"

-- isword "abc" (Result True)
-- isWord "ab1" (Result False)

I'm confuse about the way flip function works. I know it flips first two arguments but how does it work in the above code? Does it just flip the string argument and charIn "abcdefghijklmnopqrstuvwxyz" so that it looks like - all $ charIn "abcdefghijklmnopqrstuvwxyz"?

Upvotes: 0

Views: 206

Answers (4)

dfeuer
dfeuer

Reputation: 48611

Whenever you see a partial application, you can use eta (η) expansion to make things more explicit. The eta rule says that if f is any function,

f = \x -> f x

If you type

:t flip charIn "abcdefghijklmnopqrstuvwxyz"

at the GHCi prompt, you'll get a result that has an arrow (->) in it, meaning it's a function. So

flip charIn ['a' .. 'z']
=
\x -> flip charIn ['a' .. 'z'] x

Now you can apply flip to get

=
\x -> charIn x ['a' .. 'z']

Which is perhaps more clearly written

\x -> x `charIn` ['a' .. 'z']

or even, using operator section notation,

(`charIn` ['a' .. 'z'])

Upvotes: 3

jakubdaniel
jakubdaniel

Reputation: 2223

flip takes the function you pass as an argument and gives you back a function that takes parameters in reversed order, what might be confusing you is the pointfree definition of isWord and that you partially apply the flipped function to one of its arguments.

You start with charIn and flip its arguments so now it is String -> Char -> Bool, then you apply it to String argument "abc..." and get back Char -> Bool. Then you do one more partial application: all takes a function from elements to Bool and a list of elements, which Char -> Bool and String aka [Char] are. So from (Char -> Bool) -> String -> Bool, which is the type of all in this context, you get the result String -> Bool by passing in the first of the arguments.

Also you may want to consider ['a'..'z'] instead of the "abc...z".

Upvotes: 0

karakfa
karakfa

Reputation: 67527

If you have a function f with two arguments x and y in that order, i.e. f x y. If you need to fix y and make x as a free variable you can use flip to write it as flip f y x and convert to partially applied form by dropping x flip f y. When applied to x, f x y will be evaluated.

Upvotes: 0

Sebastian Redl
Sebastian Redl

Reputation: 72054

flip charIn "abcdefghijklmnopqrstuvwxyz" is the same as the lambda \c -> charIn c "abcdefghijklmnopqrstuvwxyz".

flip charIn is partially applied to the string; what remains is a function expecting one argument.

Upvotes: 2

Related Questions