8

了解 Haskell 的基本原理(Monads 等),但是已经 2 年没用了,为了干净利落地做了这个小练习,我苦苦挣扎了两个小时:

我想将一行 3*n 整数(如"1 1 1 2 2 2 3 3 3")转换为Int(如[(1,1,1),(2,2,2),(3,3,3)].

这应该以直截了当、错误捕获的方式完成。

到目前为止,我能想到的最佳解决方案包含以下内容:

groupsOf3 :: [a] -> Maybe [(a,a,a)]
groupsOf3 list =
    let fun l = case l of
            []           -> []
            (x:y:z:rest) -> (Just (x,y,z)) : (fun rest)
            _            -> [Nothing]
    in sequence $ fun list

这对我来说似乎并不优雅。我将如何更直接地编写这个函数(具有相同的界面)?

4

1 回答 1

8

我实际上认为您的解决方案看起来不错。但是,因为我无法抗拒选择棚色,你也可以考虑这样的事情:

import Control.Applicative
import Control.Monad
groupsOf3 (x:y:z:rest) = ((x,y,z):) <$> groupsOf3 rest
groupsOf3 smallList    = guard (null smallList) >> return []

您也可以考虑使用chunksOf

import Control.Monad
import Data.List.Split
convert [x,y,z] = Just (x,y,z)
convert _ = Nothing
groupsOf3 = sequence . map convert . chunksOf 3
于 2013-05-25T01:54:01.247 回答