我正在嘗試撰寫一個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 -> Boolthen 是否isVowel = True可行?我將感謝提供的任何幫助
uj5u.com熱心網友回復:
您正在(單例)串列中撰寫運算式。此外,您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)
由于Bool是成員Enum的型別類,其中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 ]
uj5u.com熱心網友回復:
你寫:
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 ] )
這就是我們所需要的。
uj5u.com熱心網友回復:
當你寫
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
正如其他答案所指出的,這可以 - 并且應該 - 只用sumor表示length,但在更一般的情況下(對變數的順序類似更新),您將使用fold:
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
]
通過在state monad 中作業,甚至可以(盡管在這種情況下不推薦)使其看起來完全是必要的:
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)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316859.html
標籤:哈斯克尔
上一篇:努力實作定時器
下一篇:函式的所有可能值的串列
