簡體   English   中英

Haskell-使用readMaybe驗證字符串的整數輸入

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM