是否可以在 Haskell 中嵌套守卫? [英] Is it possible to nest guards in Haskell?

查看:30
本文介绍了是否可以在 Haskell 中嵌套守卫?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是 Haskell 新手,正在尝试编写代码来解析数学表达式.代码:

Haskell newbie here, trying to write code to parse math expressions. Code:

isDigit :: Char -> Bool
isDigit c = c >= '0' && c <= '9'

parseNumber :: String -> Maybe (String, String)
parseNumber [] = Just ("", "")
parseNumber (h:ls)
    | isDigit h
        | p == Nothing = Just([h], ls)      -- Digit found    <<< ERROR!!
        | otherwise = Just (h:fst d, snd d) -- Ends in a digit
    | h == '.'
        | p == Nothing = Nothing                                -- Ends in a point
        | not ('.' `elem` (snd d)) = Just (h:(fst d), snd d)    -- We don't want multiple dots
    | otherwise = Nothing       -- Not a number, stop looking!
    where 
        p = parseNumber ls
        Just d = parseNumber ls -- Float version of p. Not used if p is Nothing  

这个函数应该接受一个以数字开头的字符串,并返回与表达式其余部分分开的数字.示例:

This function is supposed to take a string that starts with a number, and returns the number separated from the rest of the expression. Example:

parseNumber123.0 + 2"

parseNumber "123.0 + 2"

("123.0", "+2")

("123.0", " + 2")

我认为这个嵌套守卫的语法读起来非常好,但它不起作用.对于标记的行,错误为:

I think this nested guards' syntax reads really nicely, but it doesn't work. The error reads, for the marked line:

输入`|'解析错误

Haskell 中不允许使用链式守卫吗?还是我以某种方式写错了?另外,我有什么替代方法可以以简单的方式链接逻辑?

Are chained guards not allowed in Haskell? Or am I writting this wrongly somehow? Also, what alternatives do I have to chain logic in a simple way?

推荐答案

不需要,但如果您愿意,可以使用案例:

No, but you can use cases if you'd like:

parseNumber :: String -> Maybe (String, String)
parseNumber [] = Just ("", "")
parseNumber (h:ls)
    | isDigit h =
         case () of
           () | p == Nothing -> Just([h], ls)
              | otherwise -> Just (h:fst d, snd d) -- Ends in a digit
    | h == '.' =
         case () of
           () | p == Nothing -> Nothing
              | not ('.' `elem` (snd d)) -> Just (h:(fst d), snd d)
    | otherwise = Nothing
    where 
        p      = parseNumber ls
        Just d = parseNumber ls

或者,多路 if 以类似的方式工作(if True | p1 -> b ; | p2 -> c).

Alternatively, multiway if works in a similar manner (if True | p1 -> b ; | p2 -> c).

这篇关于是否可以在 Haskell 中嵌套守卫?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆