Categories

See More
Popular Forum

MBA (4887) B.Tech (1769) Engineering (1486) Class 12 (1030) Study Abroad (1004) Computer Science and Engineering (988) Business Management Studies (865) BBA (846) Diploma (746) CAT (651) B.Com (648) B.Sc (643) JEE Mains (618) Mechanical Engineering (574) Exam (525) India (462) Career (452) All Time Q&A (439) Mass Communication (427) BCA (417) Science (384) Computers & IT (Non-Engg) (383) Medicine & Health Sciences (381) Hotel Management (373) Civil Engineering (353) MCA (349) Tuteehub Top Questions (348) Distance (340) Colleges in India (334)
See More

Haskell function application and currying

General Tech Learning Aids/Tools

Max. 2000 characters
Tuteehub
Replies

usr_profile.png

User

( 5 months ago )

I am always interested in learning new languages, a fact that keeps me on my toes and makes me (I believe) a better programmer. My attempts at conquering Haskell come and go - twice so far - and I decided it was time to try again. 3rd time's the charm, right?

Nope. I re-read my old notes... and get disappointed :-(

The problem that made me lose faith last time, was an easy one: permutations of integers. i.e. from a list of integers, to a list of lists - a list of their permutations:

[int] -> [[int]]

This is in fact a generic problem, so replacing 'int' above with 'a', would still apply.

From my notes:

I code it first on my own, I succeed. Hurrah!

I send my solution to a good friend of mine - Haskell guru, it usually helps to learn from gurus - and he sends me this, which I am told, "expresses the true power of the language, the use of generic facilities to code your needs". All for it, I recently drank the kool-aid, let's go:

permute :: [a] -> [[a]]
permute = foldr (concatMap.ins) [[]]
   where ins x []     = [[x]]
         ins x (y:ys) = (x:y:ys):[ y:res | res <- ins x ys]

Hmm. Let's break this down:

bash$ cat b.hs
ins x []     = [[x]]
ins x (y:ys) = (x:y:ys):[ y:res | res <- ins x ys]

bash$ ghci
Prelude> :load b.hs
[1 of 1] Compiling Main             ( b.hs, interpreted )
Ok, modules loaded: Main.

*Main> ins 1 [2,3]
[[1,2,3],[2,1,3],[2,3,1]]

OK, so far, so good. Took me a minute to understand the second line of "ins", but OK: It places the 1st arg in all possible positions in the list. Cool.

Now, to understand the foldr and concatMap. in "Real world Haskell", the DOT was explained...

(f . g) x

...as just another syntax for...

f (g x) 

And in the code the guru sent, DOT was used from a foldr, with the "ins" function as the fold "collapse":

*Main> let g=concatMap . ins
*Main> g 1 [[2,3]]
[[1,2,3],[2,1,3],[2,3,1]]

OK, since I want to understand how the DOT is used by the guru, I try the equivalent expression according to the DOT definition, (f . g) x = f (g x) ...

*Main> concatMap 
usr_profile.png

User

( 5 months ago )

(f . g) x = f (g x)

This is true. You concluded from that that

(f . g) x y = f (g x y)

must also be true, but that is not the case. In fact, the following is true:

(f . g) x y = f (g x) y

which is not the same.

Why is this true? Well (f . g) x y is the same as ((f . g) x) y and since we know that (f . g) x = f (g x) we can reduce that to (f (g x)) y, which is again the same as f (g x) y.

So (concatMap . ins) 1 [[2,3]] is equivalent to concatMap (ins 1) [[2,3]]. There is no magic going on here.

Another way to approach this is via the types:

. has the type (b -> c) -> (a -> b) -> a -> cconcatMap has the type (x -> [y]) -> [x] -> [y]ins has the type t -> [t] -> [[t]]. So if we use concatMap as the b -> c argument and ins as the a -> b argument, then a becomes tb becomes [t] -> [[t]] and c becomes [[t]] -> [[t]] (with x = [t] and y = [t]).

So the type of concatMap . ins is t -> [[t]] -> [[t]], which means a function taking a whatever and a list of lists (of whatevers) and returning a list of lists (of the same type).

what's your interest