tags:

views:

220

answers:

6

Hi,

I want to write the code that will output :

 length [1,2,3] => 3

In Ruby, I could do it like :

puts "length [1,2,3] => #{[1,2,3].length}"

Following try is Haskell failed...

  Prelude Data.List> print "length [1,2,3]"
  "length [1,2,3]"
  Prelude Data.List> print (length [1,2,3])
  3
  Prelude Data.List> print "length [1,2,3]" (length [1,2,3])

  <interactive>:1:0:
    Couldn't match expected type `Int -> t'
       against inferred type `IO ()'
   In the expression: print "length [1,2,3]" (length [1, 2, 3])
   In the definition of `it':
        it = print "length [1,2,3]" (length [1, 2, 3])
   Prelude Data.List>
+3  A: 

You could use something like

putStr "length [1,2,3] => "
print (length [1,2,3])

EDIT:

If you want to do it like a function, to pass any list and write its length, you could do it this way:

print_length :: Show a => [a] -> IO ()
print_length xs = print ("length " ++ show xs ++ " => " ++ show (length xs))

Main> print_length [1,2,3,4,5]
"length [1,2,3,4,5] => 5"

Main> print_length []
"length [] => 0"

Of course, as commented above, you could use putStrLn instead of print.

yeyeyerman
Is three any way write them in one line?
pierr
+7  A: 

Strings are really just lists. So you can convert the number returned from length and append it to your other string with normal list functions:

print $ "length [1,2,3] " ++ show (length [1,2,3])
CiscoIPPhone
+5  A: 

Try this in ghci:

Prelude> :t print
print :: (Show a) => a -> IO ()

As you can see, the print function accepts only one argument, while the code above supplied two.

Instead, try this:

putStrLn ("length [1,2,3] => " ++ show (length [1,2,3]))

It's joining the two strings with ++ and then prints it.

L. Kolmodin
+3  A: 

Additionally to what others said you can also use the monadic bind operator >> to combine the two IO actions:

putStr "length [1,2,3]: " >> print (length [1,2,3])

This is equivalent to combining them with do-notation:

do putStr "length [1,2,3]: "
   print (length [1,2,3])
sth
+3  A: 

While the other posters here mention many of the 'right' ways to do string interpolation, there is a fancier way using quasiquotation and the interpolatedstring-perl6 library:

{-# LANGUAGE QuasiQuotes, ExtendedDefaultRules #-}

import Text.InterpolatedString.Perl6 (qq)

main = putStrLn [$qq| length [1,2,3] => ${length [1,2,3]} |]

In fact there is also an interpolatedstring-qq library which offers a Ruby syntax.

{-# LANGUAGE QuasiQuotes, ExtendedDefaultRules #-}

import Text.InterpolatedString.QQ (istr)

main = putStrLn [$istr| length [1,2,3] => #{length [1,2,3]} |]

That said, you probably should just use show and ++ or concat to glue together the strings

main = putStrLn $ "length [1,2,3] => " ++ show (length [1,2,3])

or

main = putStrLn $ concat ["length [1,2,3] => ", show $ length (1,2,3)]

The latter tends to look nicer, code-wise, when you are gluing together a lot of string fragments.

Edward Kmett
+5  A: 

You can also just use Text.Printf

> let format s = printf "length %s => %d\n" (show s) (length s)
> format [1,2,3]
length [1,2,3] => 3

There are several string interpolation packages on Hackage http://hackage.haskell.org if you want fancier situations.

Don Stewart