如何过滤 Maybe 值
How to filter a Maybe value
我正在尝试创建一个函数来验证输入 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
这感觉像是糟糕的代码。这个应该怎么写?
另外,如果我想循环一个函数 returns Nothing
,最好的方法是什么:
所以要循环 main
函数,我正在做:
case v of
Nothing -> main
Just x -> {do something}
我会尝试这样的事情(未测试):
validateNumber :: String -> Maybe Int
validateNumber n = case (readMaybe::String -> Maybe Int) n of
(Just a) -> case n > 0 of
True -> Just n
False -> Nothing
Nothing -> Nothing
它更短更简洁。
您可以使用 mfilter
过滤 Maybe
中超出范围的值,而不是显式匹配:
import Control.Monad (mfilter)
validateNumber :: String -> Maybe Int
validateNumber = mfilter (> 0) . readMaybe
这个怎么样?
validateNumber :: String -> Maybe Int
validateNumber n = (readMaybe n) >>= inRange
甚至这样:
validateNumber :: String -> Maybe Int
validateNumber str = do
n <- readMaybe str
if n < 0 then Nothing else return n
(避免需要单独的 inRange
函数。)
我正在尝试创建一个函数来验证输入 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
这感觉像是糟糕的代码。这个应该怎么写?
另外,如果我想循环一个函数 returns Nothing
,最好的方法是什么:
所以要循环 main
函数,我正在做:
case v of
Nothing -> main
Just x -> {do something}
我会尝试这样的事情(未测试):
validateNumber :: String -> Maybe Int
validateNumber n = case (readMaybe::String -> Maybe Int) n of
(Just a) -> case n > 0 of
True -> Just n
False -> Nothing
Nothing -> Nothing
它更短更简洁。
您可以使用 mfilter
过滤 Maybe
中超出范围的值,而不是显式匹配:
import Control.Monad (mfilter)
validateNumber :: String -> Maybe Int
validateNumber = mfilter (> 0) . readMaybe
这个怎么样?
validateNumber :: String -> Maybe Int
validateNumber n = (readMaybe n) >>= inRange
甚至这样:
validateNumber :: String -> Maybe Int
validateNumber str = do
n <- readMaybe str
if n < 0 then Nothing else return n
(避免需要单独的 inRange
函数。)