0

Here is the problem, i need to write the well known twice function

(twice= \x-> \x-> x) 

but this time using (.) composition function like (.) f g.

I don't know how to solve it, cause I thought at the beginning to do like:

(.) f g = (\x -> f (g x)) 

with (g = f) so it would be like this

(.) f f = (\x -> f (f x))

but I have a

"Conflicting definitions for `f'"

running on GHCI

So, any suggestions ?

Random Dev
  • 51,810
  • 9
  • 92
  • 119
m4verick
  • 89
  • 2
  • 13
  • I think you don't have the basic syntax for Haskell right (yet) - this seems to be a bit of a mix between lambda-calculus and Haskellish syntax - maybe you can write a bit more about where this comes from. In the meantime you can have a look at my answer to see how I would assume `twice` and "solve" it – Random Dev Sep 22 '14 at 04:29
  • Ok Heres is the thing, Im actually taking a new course, its called "Fundations of Computations" and is just as you mentioned a mixture of lambda-calculus and Haskell language. They tried to teach the two thing. My twice applies two times a function f to an argue x. Then they ask me to solved the problem but this time using (.) composition function. Its very difficult to me for that you mentioned: they mix Haskell and lambda-calculus all the time. – m4verick Sep 22 '14 at 04:45
  • And indeed it's easy *if* you get your `twice` right – Random Dev Sep 22 '14 at 05:02
  • It's the same in lambda calculus - try to reduce `(((\x.(\x.x)) f) x)` - is there an `f` in the result? – Random Dev Sep 22 '14 at 05:04
  • (Hint: it's more or less the same as my answer mentions right after the start) – Random Dev Sep 22 '14 at 05:05
  • 1
    possible duplicate of [Haskell - How to write (.) f f = (\x -> f (f x)) - Correctly](http://stackoverflow.com/questions/25966257/haskell-how-to-write-f-f-x-f-f-x-correctly) – High Performance Mark Sep 22 '14 at 05:21
  • @HighPerformanceMark I don't think it's a duplicate - this one seems to have the additional problem of fighting with `twice` and syntax – Random Dev Sep 22 '14 at 06:12
  • 1
    Looks to me like two variations on the same problem - how to define composition of two functions when those two functions might be the same. – High Performance Mark Sep 22 '14 at 07:16

1 Answers1

4

I don't know how you got anything other than a parse input from this:

(.) f f = (\x -> f (f x))

but the definition you gave: twice = \x -> \x -> x has nothing to do with using something "twice" - indeed if you plug in some values:

twice a b
= (\x -> \x -> x) a b 
= (\x -> (\x -> x)) a b -- (rename the inner x)
= (\x -> (\y -> y)) a b
= ((\x -> (\y -> y)) a) b
= (\y -> y) b
= b

and indeed GHCi will tell you the same:

> let twice = \x -> \x -> x
> :t twice
twice :: t -> t1 -> t1
> twice "a" "b"
"b"

Now I guess you want something like this:

let twice f x = f (f x)

for example:

> let twice f x = f (f x)
> twice (+1) 5
7

as you can see twice (+1) adds 2 (or twice one).

Now how can you do this using (.)? - Well your intuition was wright:

> let twice f = f . f
> twice (+1) 5
7

concerning a module

As you asked for a module - this compiles (and loads into GHCi) fine on my system(s):

module Twice where

twice :: (a->a) -> a -> a
twice f = f . f

remark:

this only works if you include (.) from the prelude (or GHC.Base) - I suspect that you got some kind of excercise that hid the prelude - in this case you have to define (.) for yourself first (most likely another excercise)

if you need to implement it yourself:

(.) :: (b -> c) -> (a -> b) -> a -> c
(.) g f x = g (f x)
Random Dev
  • 51,810
  • 9
  • 92
  • 119
  • My twice is this one: twice:: (a -> a) -> a -> a twice= \x-> \x-> x. And works fine cause a probe it doing twice not False = False, I mean twice not False = not not False = False. So now i need to write this version of twice but using (.) notation, i hope to be more clearly and thanks for your answer. – m4verick Sep 22 '14 at 04:30
  • 3
    err - no ... try to use your function with `twice (+1) 0` and it will yield 0 (I even showed you why) – Random Dev Sep 22 '14 at 04:36
  • 1
    It works for your example just because "not . not == id" so you think your definition is fine just because it is the identity for the second argument. You can tell that there is something wrong because you never **use** the first argument you give in there (*why* you might ask? Well because you shadow the first `x` with the second `\x -> x` – Random Dev Sep 22 '14 at 04:38
  • Ok I understood the point and you alright it must be: twice f x = f (f x). But the other problem is that when I save it the other notation: twice f = f . f - GHCI tell me "Not in scope: `.'" any other suggestion ? – m4verick Sep 22 '14 at 05:35
  • try `let twice f = f . f` ^^ – Random Dev Sep 22 '14 at 05:39
  • I'm must writing on a module - I tell you cause perhaps you think Im writing directly on GHCI. It didn't work when I load on GHCI, it seems it didn't like de "." they said:"Lab1.hs:29:14: Not in scope: `.'" where line 29 is: "let twice f = f . f" thanks for all your help – m4verick Sep 22 '14 at 05:53
  • this should be no problem - please try and copy the addition to my answer directyl into a file (save it as `Twice.hs`) and load this - it works on both my windows and my linux VM here – Random Dev Sep 22 '14 at 06:11
  • BTW: what are the rest of the file ... did you something to hide the prelude? – Random Dev Sep 22 '14 at 06:14
  • You are alright again, I quit the line import Prelude (Show) and it worked perfect. I hope all will fine, i think so. Thanks so much for your help. – m4verick Sep 22 '14 at 06:23