Haskell 如何过滤一个值

Haskell 如何过滤一个值,haskell,monads,maybe,Haskell,Monads,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 ->

我试图创建一个函数来验证输入
字符串->可能是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
这感觉像是糟糕的代码。这应该怎么写

另外,如果我试图在函数返回
Nothing
时循环该函数,那么最好的方法是什么:

因此,要循环
main
函数,我将执行以下操作:

case v of
  Nothing -> main
  Just x  -> {do something}

我会尝试这样的方法(未经测试):


它有点简短。

您可以使用
mfilter
筛选
中超出范围的值,而不是显式匹配:

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
validateNumber::String->Maybe Int
ValidateEnumber str=do

n我从嵌套的情况开始,但认为这是我们应该尽量避免的事情???我不会用“简明”这个词来描述忽略
Functor
实例
Maybe
@chepner的代码,也许这是一个错误的词语选择。这真的很好。关于循环我的函数有什么评论吗?@matthias-函数的输入是什么?您是想在列表中查找第一个
值,还是因为
IO
操作(例如
IO(可能是Int)
)而导致的?输入是一个简单的
getline
,需要一个有效的数字。如果号码无效,我希望它能循环返回并再次询问号码。如果它是有效的,做点什么。我建议你把第二个问题作为一个新问题来问。我发现
mfilter
的类型很奇怪。似乎
MonadPlus m=>(a->Bool)->a->ma
会自然得多。(我发现了
的许多用法,确保px=x用于循环,你可以从
monad循环中使用
@4castle我该如何编写它。当我试图使用
直到
时,我只是被卡在那一行的循环上,而不是让它循环回main的开头,这样我就可以得到那一行之前的所有代码。
x@4castle谢谢你我想你可以用
guard(n@epsilonhalbe)缩短最后一行,你是在建议我将一行“缩短”为两行,这需要额外的导入,可以说不太清晰?我不喜欢
if
,但我想这是一个品味问题。关于不必要的导入,你是对的-我忘了那一行!
validateNumber :: String -> Maybe Int
validateNumber str = do
  n <- readMaybe str
  if n < 0 then Nothing else return n