如何过滤Maybe值

mat*_*ias 10 monads haskell maybe

我正在尝试创建一个验证输入的函数String -> Maybe Int.我检查输入字符串是否是数字然后检查该数字是否在一个范围内.到目前为止我有

validateNumber :: String -> Maybe Int
validateNumber n  = go $ (readMaybe::String -> Maybe Int) n
  where
    go (Just a) = inRange a
    go Nothing  = Nothing

inRange :: Int -> Maybe Int
inRange n
  | n > 0     = Just n
  | otherwise = Nothing
Run Code Online (Sandbox Code Playgroud)

这感觉就像糟糕的代码.怎么写呢?

此外,如果我试图循环一个函数,如果它返回Nothing,最好的方法是什么:

所以要循环这个main函数,我正在做:

case v of
  Nothing -> main
  Just x  -> {do something}
Run Code Online (Sandbox Code Playgroud)

Lee*_*Lee 15

您可以使用mfilter过滤范围内的超出范围的值Maybe而不是显式匹配:

import Control.Monad (mfilter)

validateNumber :: String -> Maybe Int
validateNumber = mfilter (> 0) . readMaybe
Run Code Online (Sandbox Code Playgroud)


Mat*_*hid 8

这个怎么样?

validateNumber :: String -> Maybe Int
validateNumber n = (readMaybe n) >>= inRange
Run Code Online (Sandbox Code Playgroud)

甚至这个:

validateNumber :: String -> Maybe Int
validateNumber str = do
  n <- readMaybe str
  if n < 0 then Nothing else return n
Run Code Online (Sandbox Code Playgroud)

(避免需要单独的inRange功能.)