[英]Haskell - Validate integer input from string using readMaybe
我正在嘗試驗證來自字符串的整數輸入,如果輸入字符串正確將類型更改為整數,則只需要布爾結果。 我從另一個問題嘗試了這種方法:
https://stackoverflow.com/a/30030649/3339668
這是與我的導入相關的代碼:
import Data.Char
import Data.List
import Text.Read
checkValidInt :: String -> Bool
checkValidInt strInt
| readMaybe strInt :: Maybe Int == Nothing = False
| readMaybe strInt :: Maybe Int /= Nothing = True
但是,我在加載腳本時收到以下錯誤:
Illegal operator ‘==’ in type ‘Maybe Int == Nothing’
Use TypeOperators to allow operators in types
main.hs:350:38:
Not in scope: type constructor or class ‘Nothing’
A data constructor of that name is in scope; did you mean DataKinds?
main.hs:351:35:
Illegal operator ‘/=’ in type ‘Maybe Int /= Nothing’
Use TypeOperators to allow operators in types
main.hs:351:38:
Not in scope: type constructor or class ‘Nothing’
A data constructor of that name is in scope; did you mean DataKinds?
那么Nothing是什么類型的數據呢? 如何檢查readMaybe結果是否正確?
謝謝。
我只需要一個布爾結果
可能不是。 您需要使用Maybe Int
進行模式匹配,而readMaybe
已經為您提供了這種模式,而無需任何進一步處理。
代替這個
if checkValidInt s -- try reading an Int, but throw it away
then foo (read s) -- now really read an Int and use it
else bar -- fall back
你做這個
case readMaybe s of -- try reading an Int
Just i -> foo i -- use it
Nothing -> bar -- fall back
如果foo
是正確的類型,通常不需要顯式的類型注釋。 但請參閱下文。
如果出於某種不可思議的原因,您確實需要使用checkValidInt
,則可以根據上述模式進行設置
case (readMaybe s) :: Maybe Int of
Just _ -> True
Nothing -> False
正如在另一個答案中指出的那樣, maybe
函數可以抽象掉這種模式匹配,但是我建議您盡可能地使用顯式模式匹配作為練習,以解決問題。
這是由於Haskell會解釋您的
readMaybe strInt :: (Maybe Int == Nothing = False)
如:
readMaybe strInt :: (Maybe Int == Nothing = False)
這樣做是沒有道理的。 因此,您可以使用一些括號來幫助Haskell:
(readMaybe strInt :: Maybe Int) == Nothing = False
您最好也不要重復該條件,而應使用otherwise
,因為如果重復該條件,則該程序將(除非經過優化)將進行兩次分析,因此:
checkValidInt :: String -> Bool
checkValidInt strInt
| (readMaybe strInt :: Maybe Int) == Nothing = False
| otherwise = True
由於如果條件為False
,則檢查條件以使結果為True
,反之亦然,因此使用防護沒有用,我們可以將其寫為:
checkValidInt :: String -> Bool
checkValidInt strInt = Nothing /= (readMaybe strInt :: Maybe Int)
或者,我們可以使用模式保護器 ,如果我們無法對Maybe
包裝的值的類型執行相等性檢查,則可以使用它,因此:
checkValidInt :: String -> Bool
checkValidInt strInt | Just _ <- (readMaybe strInt :: Maybe Int) = True
| otherwise = False
或者我們可以使用isJust :: Maybe a -> Bool
函數:
checkValidInt :: String -> Bool
checkValidInt strInt = isJust (readMaybe strInt :: Maybe Int)
您可以將其重寫為
import Data.Char
import Data.List
import Text.Read
checkValidInt :: String -> Bool
checkValidInt strInt =
case (readMaybe strInt :: Maybe Int) of
Nothing -> False
Just _ -> True
您可能需要的算法已經在maybe
函數的后面進行了抽象:
checkValidInt :: String -> Bool
checkValidInt = maybe False (const True) . (readMaybe :: String -> Maybe Int)
如果readMaybe
返回Nothing
,則maybe
返回False
。 否則,它將const True
應用於結果Just
值,該值返回True
而不關心Just
。 請注意,您正在專門研究readMaybe
本身的類型,而不是其返回值的類型。
或者,甚至更簡單的導入,
import Data.Maybe
checkValidInt :: String -> Bool
checkValidInt = isJust . (readMaybe :: String -> Maybe Int)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.