4

我正在尝试在 48 小时内完成为自己编写计划中的练习。我需要帮助来简化几个功能。

data LispVal = Number Integer
             | String String
             | Bool Bool

isNumber :: [LispVal] -> LispVal
isNumber []               = Bool False 
isNumber [(Number _)]     = Bool True
isNumber ((Number _):xs)  = isNumber xs
isNumber _                = Bool False

isString :: [LispVal] -> LispVal
isString []               = Bool False 
isString [(String _)]     = Bool True
isString ((String _):xs)  = isString xs
isString _                = Bool False

isNumberisString函数有很多共同的结构。我该如何分解这种通用结构?

4

1 回答 1

6

虽然您不能参数化模式匹配本身,但您可以编写自己的小型辅助函数,这样您至少不必为每个函数重复列表处理:

isString (String _) = True
isString _ = False

isNumber (Number _) = True
isNumber _ = False

all1 _ [] = False
all1 f xs = all f xs

isListOfStrings = Bool . all1 isString
isListOfNumbers = Bool . all1 isNumber

在我看来,空列表的特殊情况处理在这里并不一致。您应该考虑只使用all(以便空列表可以是任何类型的列表,类似于 Haskell 列表的工作方式)。

于 2012-04-15T21:05:23.580 回答