String 我应该如何重构Haskell代码,使其更加优雅?

String 我应该如何重构Haskell代码,使其更加优雅?,string,haskell,String,Haskell,作为练习,我编写了一个简短的Haskell函数,返回字符串的前四个字符,并将其连接起来。我很难将字符转换成字符串,于是求助于一个丑陋的replicatehack。改进此功能的最佳方法是什么?(我猜模式和输出都可以改进。) 更新:非常感谢大家。我从所有的答案和评论中学到了一些东西。我更了解类型 以下是我最终使用的代码: initFirstFour :: [a] -> [a] initFirstFour str | length str > 3 = tak

作为练习,我编写了一个简短的Haskell函数,返回字符串的前四个字符,并将其连接起来。我很难将字符转换成字符串,于是求助于一个丑陋的
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."