gpt4 book ai didi

string - Haskell:检查字符串中的元音

转载 作者:行者123 更新时间:2023-12-03 22:47:11 24 4
gpt4 key购买 nike

我是 Haskell 的新手。我想写一个代码,检查字符串中是否有元音。
我想出了这个解决方案:

n :: Int
n = 0

vowel :: String -> Bool
vowel a
| check n = a !! n
| check == 'a' || 'e' || 'i' || 'o' || 'u' || 'y' = True
| check /= 'a' || 'e' || 'i' || 'o' || 'u' || 'y' = check(n+1)
| otherwise = False

所以基本上,我想使用递归来逐个字母检查是否有元音。
我刚刚收到如下错误消息:
 Couldn't match expected type `Bool' with actual type `Char'
* In the second argument of `(||)', namely 'y'
In the second argument of `(||)', namely 'u' || 'y'
In the second argument of `(||)', namely 'o' || 'u' || 'y'
|
14 | | check /= 'a' || 'e' || 'i' || 'o' || 'u' || 'y' = check(n+1)
|

问题出在哪儿?

最佳答案

当前方法的问题

这段代码有很多问题:

  • 你定义了一个常数 n = 0 ,并以某种方式期望这是 check 中的默认值;事实并非如此;
  • 你先写check n = a !! n ,然后使用 check == ... ,一个变量只有一种类型;
  • 在 Haskell 中 =不是赋值,而是声明。一旦声明,您就不能再更改该值;
  • 你写check == 'a' || 'e' || 'i' || 'o' || 'u' || 'y' , 但是 ||== 绑的大腿要少,所以你写了 (check == 'a') || 'e' || 'i' || 'o' || 'u' || 'y' , 因为一个字符 'e'不是 bool 值(在 Haskell 中没有真实性),你不能使用 'e'作为 || 的操作数;
  • 没有索引检查,所以即使上述问题得到解决; n最终会变得那么大,你会得到一个超出范围的索引异常;
  • 您使用 !!这本身并没有错,但它被认为是低效的(O(n))并且它不是一个如此不安全的总函数。

  • 使用 any
    让我们构造一个满足需求的函数。如果我正确理解了要求,您需要检查元音中是否至少有一个元素。

    一个字符 c如果是 'a' 则是元音, 'e' , 'i' , 'o' , 'u' , 或 'y' .所以我们可以写一张支票:
    isVowel :: Char -> Bool
    isVowel c = c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y'

    但这相当不雅观。自 String然而是 Char的列表s,我们可以使用 elem :: Eq a => a -> [a]函数,所以我们可以写:
    isVowel :: Char -> Bool
    isVowel c = elem c "aeiouy"

    现在我们只需要检查是否有任何字符 c字符串的 s那是一个元音,所以我们可以写:
    vowel :: String -> Bool
    vowel s = any (\c -> isVowel c) s

    我们可以进一步改进问题。编写形式为 \x -> f x 的 lambda 表达式是没有用的.相反,我们可以简单地写 f .所以我们可以写:
    vowel :: String -> Bool
    vowel s = any isVowel s

    我们可以在 s 上应用相同的技巧:我们可以在 vowel 的头部和主体中删除它功能:
    vowel :: String -> Bool
    vowel = any isVowel

    最后我们可以制作 isVowel函数 pointfree,通过使用 flip :
    isVowel :: Char -> Bool
    isVowel = flip elem "aeiouy"

    这导致:
    isVowel :: Char -> Bool
    isVowel = flip elem "aeiouy"

    vowel :: String -> Bool
    vowel = any isVowel

    然后我们就可以测试了。例如:
    Prelude> vowel "foobar"
    True
    Prelude> vowel "qx"
    False
    Prelude> vowel "bl"
    False
    Prelude> vowel "bla"
    True

    使用递归
    any :: (a -> Bool) -> [a] -> Bool function 是一个高阶函数:它需要一个函数作为输入,这会使它难以理解。我们可以写自己的专业 any vowel 的函数功能。我们在这里处理一个列表,通常在进行列表处理时,我们至少要考虑两种模式:空列表 []和非空列表 (x:xs) .自 any相当简单,这就足够了。

    如果我们处理空列表,我们知道字符串中没有元音,所以我们可以这样写:
    vowel [] = False

    如果列表非空 (x:xs) ,它有一个头部(第一个元素) x和尾部(剩余元素) xs .如果第一个元素是元音,或者其余元素中的任何一个是元音,则字符串包含元音。所以我们可以写:
    vowel (x:xs) = isVowel x || vowel xs

    如果我们把这些放在一起(连同 isVowel 函数),我们得到:
    isVowel :: Char -> Bool
    isVowel c = elem c "aeiouy"

    vowel [] = False
    vowel (x:xs) = isVowel x || vowel xs

    关于string - Haskell:检查字符串中的元音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46364784/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com