문제

I am trying to work through the exercises in Write Yourself a Scheme in 48 Hours. I need help with simplifying couple of functions.

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

The isNumber and isString functions have lot common structure. How do I go about factoring out this common structure?

도움이 되었습니까?

해결책

While you can't parameterize the pattern match itself, you can write yourself small helper functions so you at least don't have to repeat the list handling for every function:

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

In my opinion, the special case handling of the empty list isn't consistent here. You should consider just using all instead (so that the empty list can be a list of any kind, similar to how Haskell's lists work).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top