Hi there, First of all, I would say thank you very much for all who helped me during the past days. Since I am a beginner , sometime I spent even several hours to solve a very simple problem.So, I still need your help in the future. The problem is: ******************************************************** import Random uni :: IO () -> Float uni = do xs <- newStdGen let m = (head (randoms xs) :: Float ) doubleit :: Float -> Float doubleit n = 2.0*n main = print (doubleit uni) ******************************************************** The result is: bash-2.05$ ghci ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 5.02.2, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package std ... linking ... done. Prelude> :cd test Prelude> :l random.ls can't find module `random.ls' Prelude> :l random.hs Compiling Main ( random.hs, interpreted ) random.hs:11: The last statement in a 'do' construct must be an expression Failed, modules loaded: none. Prelude> ******************************************************* What is wrong with it? Thank you very much. Kevin
There are a few things wrong with this...
uni :: IO () -> Float uni = do xs <- newStdGen let m = (head (randoms xs) :: Float )
presumably, you want 'uni' to produce a random float. in this case, it has the wrong type; it is actually an IO action that returns a Float, hence it's type should be: uni :: IO Float furthermore, IO actions (and functions in general) need to return something; since you're using 'do' notation, you need to have a call to return, something like: uni = do xs <- newStdGen let m = (head (randoms xs) :: Float) return m -- return the head or more simply uni = do xs <- newStdGen return (head (randoms xs)) then, since do { x <- f ; y x } really means "f >>= \x -> y x" which is "f >>= y", you could write this as uni = newStdGen >>= return . head . randoms (if that doesn't make sense, don't worry)
doubleit :: Float -> Float doubleit n = 2.0*n
this is fine
main = print (doubleit uni)
here's another problem. the type of uni is IO Float. the type of doubleit is Float -> Float. You can't pass an IO Float as a parameter instead of a float. what you need to do is perform the action uni, get the result, pass it to doubleit and then print that, something like: main = do v <- uni print (doubleit v) again, you can rewrite this: main = uni >> print . doubleit hope that made some sense, i gotta run - hal
What is wrong with it?
Take a look at the Wiki, which has some explanation of the IO monad (which you're using here, with the "do" notation): http://haskell.org/wiki/wiki?UsingIo http://haskell.org/wiki/wiki?ThatAnnoyingIoType http://haskell.org/wiki/wiki?UsingMonads Hope this helps! --KW 8-) -- Keith Wansbrough <kw217@cl.cam.ac.uk> http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory.
participants (4)
-
Hal Daume III -
Junjie Xu -
Keith Wansbrough -
Nick Name