如何检查元音?

  • 本文关键字:何检查 haskell
  • 更新时间 :
  • 英文 :


我正试图编写一个函数score :: Char -> Int,将字符转换为其分数。每一个以分数1开头的字母;1如果是元音,则加到字符的分数中(a, e, i, o, u)1如果是大写字符则加到分数中;一个字符这不是一个得分0的字母。例如,

score 'A' == 3
score 'a' == 2
score 'B' == 2
score 'b' == 1
score '.' == 0

这是我到目前为止的代码:

n :: Int -> Int
n = 0
isVowel :: Char -> Char
isVowel x = [if x == 'a' || x == 'e' || x == 'i' ||
x == 'o' || x == 'u' then x else x]
score :: Char -> Int
score x  =
[if isAlpha x then n+1 else n ]
[if isUpper x then n+1 else n ]
[if isVowel x then n+1 else n ]

这段代码肯定有问题,但我找不到。具体来说,有没有办法写一个检测元音的函数?我甚至不确定我写的那个是对的。或者我把isVowel的类型改成Char -> Bool如果是isVowel = True,那还行吗?我将感谢您提供的任何帮助

你在(单例)列表中编写表达式。此外,您的isVowel应该返回Bool。因此,我们可以这样实现:

isVowel :: Char ->Bool
isVowel x = x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u'

但是您忘记了大写元音(AEIOU)。我们可以用elem检查将其写得更紧凑:

isVowel :: Char -> Bool
isVowel x = x`elem`"aeiouAEIOU"

或甚至与中缀操作符的部分连在一起:

isVowel :: Char -> Bool
isVowel = (`elem`"aeiouAEIOU")

在你的score函数中,你似乎使用了一个变量n,但该变量没有在某个地方定义,而且在Haskell中所有变量都是不可变的:一旦分配了一个值,你就不能再改变它的值。

我们可以通过将三项相加来计算分数:

score :: Char -> Int
score x  = (if isAlpha x then 1 else 0) + (if isUpper x then 1 else 0) + (if isVowel x then 1 else 0)

由于BoolEnum的成员如果False映射到0,True映射到1,我们可以使用fromEnum :: Enum a => a -> Int要自动进行转换:

score :: Char -> Int
score x  = fromEnum (isAlpha x) + fromEnum (isUpper x) + fromEnum (isVowel x)

或者,就像@leftroundabout说的:我们也可以使用列表推导和检查列表,所以:

score :: Char -> Int
score x  = length [ 1 |p<- [isAlpha, isUpper, isVowel],p x]

你写:

n :: Int -> Int
n = 0

n定义为0。它将永远是0。我们不能改变它,我们已经这样定义了。

这也不是一个函数,它只是Int

n :: Int
n = 0
isVowel :: Char -> Char
isVowel x = [if x == 'a' || x == 'e' || x == 'i' ||
x == 'o' || x == 'u' then x else x]

显然有些部分很好,但首先,为什么要用括号?我们根本不需要他们。第二,返回类型应该是Bool:

isVowel :: Char -> Bool
isVowel x =  if x == 'a' || x == 'e' || x == 'i' ||
x == 'o' || x == 'u' then True else False

但是随后if只是原样返回它的测试,所以也不需要它:

isVowel :: Char -> Bool
isVowel x =     x == 'a' || x == 'e' || x == 'i' ||
x == 'o' || x == 'u' 

最后,score:

score :: Char -> Int
score x  =
[if isAlpha x then n+1 else n ]
[if isUpper x then n+1 else n ]
[if isVowel x then n+1 else n ]

这里是n+1 == 0+1 == 1,所以不需要n。事实上,

score :: Char -> Int
score x  =  sum (
[1 | isAlpha x ]  ++
[1 | isUpper x ]  ++
[1 | isVowel x ]  )

是我们所需要的。

当你写下

score x  =
[if isAlpha x then n+1 else n]
[if isUpper x then n+1 else n]
[if isVowel x then n+1 else n]

你可能有一点像Python

def score(x):
n = 0
if isAlpha(x): n+=1
if isUpper(x): n+=1
if isVowel(x): n+=1
return n

正如其他答案所指出的那样,这可以-而且应该-仅用sumlength来表示,但在更一般的情况下(对变量进行顺序类似的更新),您将使用折叠:

import Data.List
score x = foldl' (n p -> if p x then n+1 else n) 0
[isAlpha, isUpper, isVowel]

或者

score x = foldl' (flip id) 0
[ n -> if isAlpha x then n+1 else n
, n -> if isUpper x then n+1 else n
, n -> if isVowel x then n+1 else n
]

甚至可以(尽管在这种情况下不推荐)通过在状态单子中工作来使它看起来完全命令式:

import Control.Monad
import Control.Monad.Trans.State
score = (`execState`0) $ do
when (isAlpha x) $ modify (+1)
when (isUpper x) $ modify (+1)
when (isVowel x) $ modify (+1)

相关内容

  • 没有找到相关文章

最新更新