[英]Print a string in list notation in Haskell
我有一个函数,其中字符串被重复打印特定次数。 但是,如果给定一个负数,则该函数应打印出一个空列表。
main = print (repeat (-1) "Hello World")
repeat 1 x = x
repeat n x
| n < 0 = *???*
| n > 0 = x ++ repeat (n-1) x
我该怎么办,以便将空列表打印在方括号中而不是引号中?
看repeat
签名
repeat :: Int -> [a] -> [a]
我们希望n <= 0
情况为“空”。 我们可以使用monoid:
import Data.Monoid
repeat :: Int -> [a] -> [a]
...
| n <= 0 = mempty
或写清单:
| n <= 0 = []
更新
如果我们希望为空字符串打印[]
,则必须“扩展” print
功能,如下所示:
print' [] = putStrLn "[]"
print' z = print z
目前尚不清楚您要做什么,因此问题出在哪里,所以这里有一些可能的解释。
例如,考虑:let test = if(True)then [] else ['a']打印测试“”
如果这是问题,我不知道如何更改默认行为。 最好的方法是避免使用“打印”,而是结合使用“ putStrLn”和您自己的打印功能:
myShow :: String -> String
myShow "" = "[]"
myShow a = a
main = putStrLn . myShow $ (repeat (-1) "Hello World")
在这种情况下,您需要更改重复功能:
repeat 1 x = [x]
repeat n x
| n < 0 = []
| n > 0 = x : repeat (n-1) x
现在,签名将repeat :: (Num a, Ord a) => a -> t -> [t]
,空情况将为[]。
您的问题实际上是使用Haskell的“无限”列表可以解决的一个难题。 这个想法是生成输入字符串的重新排列的无限列表,然后根据需要获取尽可能多的列表,然后决定如何打印该有限子列表:
printNTimes :: Int -> String -> IO ()
printNTimes n s = putStrLn . customShow . take n . repeat $ s
where
customShow [] = "[]"
customShow ss = concat ss
标准的Prelude
函数( repeat
(与您自己定义的函数不同))采用某事物的一个示例,并通过简单地在“ forever”(一遍又一遍)上重复来创建此事物的无限列表。 所以:
repeat "hello" = ["hello", "hello", "hello", ...] -- not valid Haskell
repeat 3 = [3, 3, 3, ...] -- not valid Haskell
当然,我们永远无法在任何只有有限内存的机器上显示或以任何其他完全具体的方式实现无限列表。 但这不是问题,因为我们只需要列表的前n
元素,这就是在上面的函数中take n
要做的。 请注意,当n <= 0
, take n
返回空列表,而不管其适用于什么,特别是take (-1) ["hello", "hello", ...] = []
。
一旦有了我们感兴趣的n
元素,我们就可以按自己喜欢的方式显示它们,这就是customShow
作用:如果看到一个空列表,则显示“ []”,否则它会连接我们所有的字符串只是从我们的重复列表中取出,并合并成一个长字符串,并以通常的方式显示出来。
在旁注中,在Haskell中最好的做法是分离纯函数,例如customShow . take n . repeat
customShow . take n . repeat
printNTimes
IO
操作(例如putStrLn
customShow . take n . repeat
printNTimes
一部分。 在printNTimes
,纯printNTimes
和不纯printNTimes
是根据成分组合在一起的,但是最好写一些类似...
showNTimes :: Int -> String -> String
showNTimes n = customShow . take n . repeat
where
customShow [] = "[]"
customShow ss = concat ss
然后,也许在您的main
功能中,您将得到一个类似这样的序列:
main :: IO ()
main = do
s <- getLine
...
putStrLn $ showNTimes 10 s
...
祝您拥有Haskelling好运! 这是一门美丽的语言,值得学习。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.