部分功能组成的语法

发布于 2025-02-13 13:56:08 字数 927 浏览 0 评论 0 原文

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)。没有)n = false 。我想要的很明显。找到除了ASCII字母或空间以外的任何字符。

尽管尝试了各种语法,但我仍在此行中遇到编译错误,类似

• Couldn't match expected type ‘Bool’
                  with actual type ‘Char -> Bool’
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

I'm struggling with this line: any ((isAsciiAlpha || C.isSpace) . not) n = False. What I want is pretty obvious; find if any of the characters is something other than an ASCII alphabet or a space.

In spite of trying various syntaxes, I keep getting compilation error on this line, something like

• Couldn't match expected type ‘Bool’
                  with actual type ‘Char -> Bool’

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

背叛残局 2025-02-20 13:56:08

您无法使用 (||):: bool - &gt;布尔 - &gt; bool 在两个功能上:参数应为 bool s。您可以做的是构造一个函数,该函数映射 c isasciialpha c || c.isspace c ,so \ c - &gt; isasciialpha c || c.isspace c ,或者您可以使用 lifta2 ::应用f =&gt; (a - &gt; b - &gt; c) - &gt; fa-&gt; fb - &gt; f C 带有 lifta2(||)isasciialpha c.isspace 也应应用于功能的结果,因此:

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 -- …

您还可以使用 (&lt; ||&gt;)::应用a =&gt;布尔 - &gt;布尔 - &gt; bool 或它的shortcircuitng版本 (||^)::::: monad m =&gt; m bool - &gt; m bool - &gt; m bool 软件包。

You can not use (||) :: Bool -> Bool -> Bool on two functions: the parameters should be both Bools. What you can do is construct a function that maps a character c on isAsciiAlpha c || C.isSpace c, so \c -> isAsciiAlpha c || C.isSpace c, or you can use liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c with liftA2 (||) isAsciiAlpha C.isSpace. The not :: Bool -> Bool should also be applied on the result of the function, so:

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 -- …

You can also make use of (<||>) :: Applicative a => a Bool -> a Bool -> a Bool or its shortcircuitng version (||^) :: Monad m => m Bool -> m Bool -> m Bool of the protolude package.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文