Haskell - 使用readMaybe验证字符串中的整数输入

时间:2018-03-19 15:47:08

标签: validation haskell

我正在尝试验证字符串中的整数输入,如果输入字符串正确地将类型更改为整数,我只需要一个布尔结果。我从另一个问题尝试了这个方法:

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?

那么什么样的数据类型什么都没有?如何检查readMaybe是否正常结果?

感谢。

4 个答案:

答案 0 :(得分:4)

  

我只需要一个布尔结果

可能不是。您需要ApplicationListener模式匹配,而SessionDisconnectEvent已经为您提供了该功能而无需进一步处理。

而不是这个

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函数将此模式匹配抽象出来,但我建议您尽可能使用显式模式匹配作为练习,以获得它的悬念。

答案 1 :(得分:3)

这是因为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

由于您检查的条件是True如果条件为False,反之亦然,则使用防护是没有用的,我们可以将其写为:

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)

答案 2 :(得分:2)

您可以将其重写为

import Data.Char
import Data.List
import Text.Read

checkValidInt :: String -> Bool
checkValidInt strInt =
  case (readMaybe strInt :: Maybe Int) of
    Nothing -> False
    Just _  -> True

答案 3 :(得分:1)

这里需要的算法已经在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)