Haskell中的字符串插值

pie*_*fou 20 string haskell

我想编写将输出的代码:

length [1,2,3] => 3   
Run Code Online (Sandbox Code Playgroud)

在Ruby中,我可以这样做:

puts "length [1,2,3] => #{[1,2,3].length}"
Run Code Online (Sandbox Code Playgroud)

以下尝试是Haskell失败了......

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>
Run Code Online (Sandbox Code Playgroud)

Don*_*art 36

您也可以使用Text.PrintfGHC基础库中包含的内容:

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

如果你想要更好的情况,Hackage http://hackage.haskell.org上有几个字符串插值包.


Edw*_*ETT 33

虽然这里的其他海报提到了许多"正确"的方法来进行字符串插值,但使用quasiquotation和interpolatedstring-perl6库有一种更好的方式:

{-# LANGUAGE QuasiQuotes, ExtendedDefaultRules #-}

import Text.InterpolatedString.Perl6 (qq)

main = putStrLn [$qq| length [1,2,3] => ${length [1,2,3]} |]
Run Code Online (Sandbox Code Playgroud)

实际上还有一个interpolatedstring-qq库,它提供了Ruby语法.

{-# LANGUAGE QuasiQuotes, ExtendedDefaultRules #-}

import Text.InterpolatedString.QQ (istr)

main = putStrLn [$istr| length [1,2,3] => #{length [1,2,3]} |]
Run Code Online (Sandbox Code Playgroud)

也就是说,您可能应该使用show和++或concat将字符串粘合在一起

main = putStrLn $ "length [1,2,3] => " ++ show (length [1,2,3])
Run Code Online (Sandbox Code Playgroud)

要么

main = putStrLn $ concat ["length [1,2,3] => ", show $ length (1,2,3)]
Run Code Online (Sandbox Code Playgroud)

当你将许多字符串片段粘在一起时,后者往往看起来更好,代码方面.

  • 每次使用template-haskell时,编译器都必须在编译时加载所有依赖项.它可能很慢.我倾向于不为像字符串插值这样的简单方便而产生这样的代价,当替代方案的长度几乎相同时,并且当我使用的近似Haskell语法的quasiquotation无法解析时,不太可能要求我完全重构我的代码我需要的一些句法结构. (8认同)
  • 您可以使用 `intercalate` 代替 `concat`,这样就可以避免手动插入分隔空格: `main = putStrLn $ intercalate " " ["length [1,2,3] =&gt;", show $length (1, 2,3)]` (2认同)

Cis*_*one 15

字符串实际上只是列表.因此,您可以转换从长度返回的数字,并将其附加到具有正常列表函数的其他字符串:

print $ "length [1,2,3] " ++ show (length [1,2,3])
Run Code Online (Sandbox Code Playgroud)


Dmi*_*lov 7

使用格式从功能的文本格式,简单的库:

import Text.Format
format "length [1,2,3] => {0}" [show $ length [1,2,3]]
Run Code Online (Sandbox Code Playgroud)