String 我应该如何重构Haskell代码,使其更加优雅?
作为练习,我编写了一个简短的Haskell函数,返回字符串的前四个字符,并将其连接起来。我很难将字符转换成字符串,于是求助于一个丑陋的String 我应该如何重构Haskell代码,使其更加优雅?,string,haskell,String,Haskell,作为练习,我编写了一个简短的Haskell函数,返回字符串的前四个字符,并将其连接起来。我很难将字符转换成字符串,于是求助于一个丑陋的replicatehack。改进此功能的最佳方法是什么?(我猜模式和输出都可以改进。) 更新:非常感谢大家。我从所有的答案和评论中学到了一些东西。我更了解类型 以下是我最终使用的代码: initFirstFour :: [a] -> [a] initFirstFour str | length str > 3 = tak
replicate
hack。改进此功能的最佳方法是什么?(我猜模式和输出都可以改进。)
更新:非常感谢大家。我从所有的答案和评论中学到了一些东西。我更了解类型
以下是我最终使用的代码:
initFirstFour :: [a] -> [a]
initFirstFour str
| length str > 3 = take 4 str
| otherwise = error "Need at least four characters."
更新2:将第二个模式从xs更改为u per ptival的注释。懒惰的评估FTW
更新3:tew88评论中的清洁卫士
concatFirstFour (a:b:c:d:_) = [a,b,c,d]
concatFirstFour _ = error "Need at least four characters."
或
但最后一个并没有在候选名单上失败
另外请注意,您不需要指定类型为[Char](或字符串),因为您在代码中从未使用此假设。设为[a]->[a]。字符串只是字符列表,因此不需要将字符转换为字符串,然后连接字符串。有几种不同的方法可以做到这一点 首先,如果您想要一个只有一个元素的列表,可以使用
[x]
。因此:
concatFirstFour (a:b:c:d:_) = [a] ++ [b] ++ [c] ++ [d]
但这并不是真的必要。你可以这样做:
concatFirstFour (a:b:c:d:_) = [a, b, c, d]
或者这个:
concatFirstFour (a:b:c:d:_) = a:b:c:d:[]
或者,我更喜欢的方式:
concatFirstFour str = take 4 str
由于
str
只是一个列表,您可以获取前四个字符以获得一个新的“字符串”。类似于Ptival使用模式匹配的解决方案。但是对于小于4个字符的字符串,这个不会出错
concatFirstFour (a:b:c:d:_) = [a,b,c,d]
concatFirstFour xs = xs
您可以考虑使用“否则”关键字作为守护表达式的一部分:
initFirstFour :: [a] -> [a]
initFirstFour xs
| length xs > 3 = take 4 xs
| otherwise = error "Need at least four characters."
我认为这比您选择的模式匹配方法更具可读性(也更优雅)。concatFirstFour::[a]->[a]
更好。请注意,您不需要在代码的最后一行命名xs
,因为函数体中从未使用参数。您可以将其替换为wilcard。
这在无限列表中失败,与其他答案不同。
concatFirstFour (a:b:c:d:_) = [a,b,c,d]
concatFirstFour xs = xs
initFirstFour :: [a] -> [a]
initFirstFour xs
| length xs > 3 = take 4 xs
| otherwise = error "Need at least four characters."