我正在努力完成Write Yourself a Scheme in 48 Hours中的练习。我需要帮助来简化几个功能。
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
isNumber
和isString
函数有很多共同的结构。我该如何解决这个共同的结构呢?
答案 0 :(得分: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列表的工作方式)。