ssm
ssm

Reputation: 5373

Differences between a line in a haskell source file and one in GHCI

Haskell newbie here so please excuse if the question is too simple. Its just that I dont seem to be able to get a handle on why some things are ok in a file, but not in GHCI. For example, I have the following lines in a file:

showLst :: [[Int]] -> IO ()
showLst = putStrLn . unlines . map show

This takes a m x n array and prints the result on the screen. A very convenient function. However, when I am doing a quick check on GHCI and I want the same functionallity, I try to define the same function in GHCI like so:

>> let showLst = putStrLn . unlines . map show
>> showLst [[1,2,3], [4,5,6], [7,8,9]]

I get a type error. So I try several variations:

>> (showLst [[1,2,3], [4,5,6], [7,8,9]]) :: IO ()
>> (showLst:: [[Int]] -> IO ()) [[1,2,3], [4,5,6], [7,8,9]] 
>> (showLst [[1,2,3], [4,5,6], [7,8,9]]) :: [[Int]] -> IO () -- which us wrong anyway
>> showLst [[1,2,3], [4,5,6], [7,8,9]] :: [[Int]] -> IO () -- which is also wrong

etc and they all fail. This seems to be a very simple thing to do, but not sure why I am finding this to be so difficult. I must be missing something that is really fundamental. Can someone please let me know what I am doing wong ?

Upvotes: 5

Views: 113

Answers (1)

max taldykin
max taldykin

Reputation: 12898

The problem is that due to monomorphism restriction GHCi defaults type of your list element to ():

Prelude> let showLst = putStrLn . unlines . map show
Prelude> :t showLst 
showLst :: [()] -> IO ()

You can disable this restriction and get general type:

Prelude> :set -XNoMonomorphismRestriction 
Prelude> let showLst = putStrLn . unlines . map show
Prelude> :t showLst 
showLst :: Show a => [a] -> IO ()

Or you can specify desired type manually:

Prelude> let showLst = putStrLn . unlines . map show :: [[Int]] -> IO ()

Upvotes: 10

Related Questions