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>
share|improve this question
8  
BTW, using print on a string will print it with quotes (and escaped). Try putStr or putStrLn to print the string as-is. – L. Kolmodin Aug 12 '09 at 7:57
up vote 12 down vote accepted

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])
share|improve this answer

You can also just use Text.Printf which is included in the GHC base libraries:

> 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.

share|improve this answer

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.

share|improve this answer
    
Why is it better to use concat or ++ than QuasiQuotes? – Vlad the Impala Mar 31 '13 at 6:52
3  
Every time you use template-haskell your compiler has to load up at compile time all of your dependencies. It can be quite slow. I tend not to incur that cost for a trivial convenience like string interpolation, when the alternative is almost the same length, and unlikely to require me to completely refactor my code when the quasiquotation which approximates Haskell syntax that I'm using can't parse some syntactic construct I need. – Edward KMETT Mar 31 '13 at 18:25
    
@VladtheImpala, another reason is that each QuasiQuoter requires the reader to understand a new language, so they won't necessarily be able to see bugs straight away. I'd only use a QuasiQuoter if my project used it a lot, and so I can expect developers to know how it works. – povman Mar 31 '15 at 0:12

Use format function from text-format-simple library:

import Text.Format
format "length [1,2,3] => {0}" [show $ length [1,2,3]]
share|improve this answer

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.

share|improve this answer

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.

share|improve this answer
    
Is three any way write them in one line? – Bin Chen Aug 12 '09 at 7:53

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])
share|improve this answer

if you just want to debug stuff like:

inc :: Int -> Int
inc x = [debug|1+x|]

inc 2
-- prints "1+x = 3"
-- returns 3

this QuasiQuoter might help:

{-# LANGUAGE TemplateHaskell #-}
module Template where
import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Language.Haskell.TH.Syntax
import Language.Haskell.Meta.Parse
import Debug.Trace

-- | e.g. f x = [debug|1+x|]
debug :: QuasiQuoter
debug = QuasiQuoter traceExp undefined undefined undefined

-- | e.g. traceExp "1+x"  ->  [| trace "1+x = $([|1+x|])" (1+x) |]
--   (or something)
traceExp :: String -> Q Exp
traceExp s = [|( trace $(showExp s) $(parseE s) )|]

-- | e.g. showExp "1+x"  ->  [| "1+x" ++ " = " ++ show (1+x) |]
showExp :: String -> Q Exp
showExp s = [|( $(stringE s) ++ " = " ++ show $(parseE s) )|]

-- | e.g. parseE "1+x"  ->  (UInfixE (LitE (IntegerL 1)) (VarE +) (VarE x))
parseE :: String -> Q Exp
parseE = return . either (const undefined) id . parseExp

-- $ cabal install haskell-src-exts
-- $ cabal install haskell-src-meta

the variables are captured dynamically. I had written it while learning Template Haskell, but debug does work for debugging stuff during development.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.