haskell中的NILL值

时间:2010-05-28 23:44:10

标签: haskell

我从用户那里获得输入(x),通过让y =(读取x):: Int将其转换为Int然后我希望该函数在用户什么都不给的情况下以特殊方式运行(空字符串)。 / p>

-- In this place I would like to handle situation in which user
-- gave empty string as argument
-- this doesnt work :/
yearFilter [] y = True

--This works fine as far as y is integer
yearFilter x y  | x == (objectYear y) = True
                | otherwise = False

感谢您的帮助, 再见

4 个答案:

答案 0 :(得分:14)

也许你想要一个Maybe类型?如果用户输入空字符串,则函数返回Nothing;否则返回Just n,其中n是用户输入的内容?

userInt :: String -> Maybe Int
userInt [] = Nothing
userInt s  = Just $ read s

(我还没有编译这段代码。)

答案 1 :(得分:4)

在这种情况下,Maybe可能不够:您有三个需要担心的条件:

  1. 用户未输入任何内容
  2. 用户输入有效
  3. 用户输入无法解析
  4. 此数据类型和函数直接表达了这一点:

    data Input a = NoInput | Input a |  BadInput String
        deriving (Eq, Show)
    
    input :: (Read a) => String -> Input a
    input "" = NoInput
    input s =
        case filter (null.snd) (reads s) of
            ((a,_):_) -> Input a
            otherwise -> BadInput s
    

    请注意,它不使用不完整的函数read,而是使用reads,它不会在无法转换的输入上出错。 reads有一个有点尴尬的界面,唉,所以我几乎总是把它包装在一个函数中,在这里返回Maybe a或类似的东西。

    使用示例:

    > input "42" :: Input Int
    Input 42
    > input "cat" :: Input Int
    BadInput "cat"
    > input "" :: Input Int
    NoInput
    

    我会像这样编写yearFilter函数:

    yearFilter :: Maybe Int -> Int -> Bool
    yearFilter Nothing  _ = True
    yearFilter (Just x) y = x == objectYear y
    

    然后我将用户输入处理为:

    inputToMaybe :: Input a -> Maybe a
    inputToMaybe (Input a) = Just a
    inputToMaybe _         = Nothing
    
    do
        a <- input `fmap` getLine
        case a of
            BadInput s -> putStrLn ("Didn't understand " ++ show s)
            otherwise  -> ... yearFilter (inputToMaybe a) ....
    

    注意:我已经清理了yearFilter中的代码:无需使用防护来从测试中生成布尔值 - 只需返回测试,函数应用程序(objectYear)更紧密地绑定比运算符(==)所以删除了括号,用_替换了未使用输入的名称。


    好吧,我承认我无法帮助自己....我已经重写yearFilter了,这次我倾向于写下来:

    yearFilter :: Maybe Int -> Int -> Bool
    yearFilter x y = maybe True (== objectYear y) x
    

    了解Maybemaybe是关于Haskell的第一件事让我爱上了这门语言。

答案 2 :(得分:3)

除非您明确定义它,否则没有NULL。你可以检查这样的空字符串。

readInput :: IO ()
readInput = do
   ln <- getLine
   if valid ln
      then -- whatever
      else -- whatever

valid x
    | null x                = False
    | not istJust convert x = False
    | otherwise             = True
where convert :: String -> Maybe Int
      convert = fmap fst $ listToMaybe  . reads $ "f"

答案 3 :(得分:2)

'read'函数无法将空字符串转换为int,如果尝试这样做会导致错误。在转换为int之前,您需要测试输入是否为空字符串。如果要在用户输入空字符串时使用默认值(例如0),则可以执行以下操作:

let y = if null x then 0 else read x