[英]Syntax for partial function composition
module Luhn (isValid) where
import qualified Data.Char as C
isAsciiAlpha :: Char -> Bool
isAsciiAlpha = C.isAsciiLower || C.isAsciiUpper
isValid :: String -> Bool
isValid n
| any ((isAsciiAlpha || C.isSpace) . not) n = False
| otherwise = ys > 1 && sum xxs `mod` 10 == 0
where
xs = reverse [c | c <- n, isAsciiAlpha c]
ys = length xs
zs = zip xs (cycle [1, 2])
xxs = [convert x y | (x, y) <- zs]
convert :: Char -> Int -> Int
convert c mul =
do
let n = C.digitToInt c
case () of
_
| mul == 2 && (n > 4) -> n * mul - 9
| otherwise -> n * mul
我正在为这条线苦苦挣扎: any ((isAsciiAlpha || C.isSpace) . not) n = False
。 我想要的很明显; 查找是否有任何字符不是 ASCII 字母或空格。
尽管尝试了各种语法,但我在这一行不断收到编译错误,比如
• Couldn't match expected type ‘Bool’
with actual type ‘Char -> Bool’
你不能在两个函数上使用(||) :: Bool -> Bool -> Bool
:参数应该都是Bool
。 您可以做的是构造一个函数,将字符c
映射到isAsciiAlpha c || C.isSpace c
isAsciiAlpha c || C.isSpace c
,所以\c -> isAsciiAlpha c || C.isSpace c
\c -> isAsciiAlpha c || C.isSpace c
,或者你可以使用liftA2 :: Applicative f => (a -> b -> c) -> fa -> fb -> fc
with liftA2 (||) isAsciiAlpha C.isSpace
。 not :: Bool -> Bool
也应该应用于函数的结果,所以:
import Control.Applicative(liftA2)
isAsciiAlpha :: Char -> Bool
isAsciiAlpha = liftA2 (||) C.isAsciiLower C.isAsciiUpper
isValid :: String -> Bool
isValid n
| any (not . liftA2 (||) isAsciiAlpha C.isSpace) n = False
| otherwise = ys > 1 && sum xxs `mod` 10 == 0
where -- …
您还可以使用(<||>) :: Applicative a => a Bool -> a Bool -> a Bool
或其短路版本(||^) :: Monad m => m Bool -> m Bool -> m Bool
protolude
包的布尔值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.