【问题标题】:Wrong in my guard expression?我的警卫表情有问题吗?
【发布时间】:2016-05-01 21:15:44
【问题描述】:

我正在编写一个小程序,它从另一个字符串(即“输入字符串”(参数))“构建”一个字符串。但是我收到一个解析错误(在输入'='上)。我怀疑我的守卫表达有问题?

checkCons :: Char -> Bool 
checkCons x = notElem x ['a','e','i','o','u','y'] 


rovarSprak :: [Char] -> [Char] -> [Char]
rovarSprak [] res = res
rovarSprak (c:restOfStr) res
    | (checkCons c) == True  =  rovarSprak restOfStr (c:'o':c:res)
    | otherwise = rovarSprak restOfStr (c:res)

如果我打电话:rovarSprak "abc" []。我期待"abobcoc"

观察checkCons 函数是否正常工作。

【问题讨论】:

    标签: haskell guard


    【解决方案1】:

    我认为您的旧代码没有正确缩进。如果我在以下位置运行 ghc 编译器:

    rovarSprak :: [Char] -> [Char] -> [Char]
    rovarSprak [] res = res
    rovarSprak (c:restOfStr) res
    | (checkCons c) == True  =  rovarSprak restOfStr (c:'o':c:res)
    | otherwise = rovarSprak restOfStr (c:res)
    

    它给出了一个错误:

    strep.hs:8:1: parse error on input ‘|’
    

    将其重写为:

    rovarSprak :: [Char] -> [Char] -> [Char]
    rovarSprak [] res = res
    rovarSprak (c:restOfStr) res
        | (checkCons c) == True  =  rovarSprak restOfStr (c:'o':c:res)
        | otherwise = rovarSprak restOfStr (c:res)
    

    解决编译错误。

    另外如果尝试复现,结果是:

    "cocboba"
    

    警卫工作正常,您的代码的唯一问题是在递归调用中:

    rovarSprak restOfStr (c:'o':c:res)
    --                   ^push in front
    

    您将结果推送到新列表的前面,而您可能希望它位于尾部。

    您可以通过不使用累加器来解决这个问题,而是直接发射元素。例如:

    rovarSprak :: [字符] -> [字符] 罗瓦斯普拉克 [] = [] rovarSprak (c:restOfStr) | (checkCons c) == True = c : 'o' : c : (rovarSprak restOfStr) |否则 = c : rova​​rSprak restOfStr

    (粗体字和笔画冗余代码元素的排放)。这也允许生成惰性列表:也许您只对输出的前三个元素感兴趣,或者输入是一个无限列表。

    我建议的最后一个优化是交换rovarSprak 的两行:

    rovarSprak :: [字符] -> [字符] rovarSprak (c:restOfStr) | checkCons c = c : 'o' : c : (rovarSprak restOfStr) |否则 = c : rova​​rSprak restOfStr 罗瓦斯普拉克 [] = []

    这是因为您更有可能在第一行找到匹配项:对于长度为 N 的列表,第一个模式将有 N 个调用,并且one 在第二个模式上。

    【讨论】:

    • @J.doe:您是否打算将您的代码可能与编辑中的代码一样?否则,您可能忘记提及代码中的某个元素。
    • 问题是,从我的示例代码中看不到(因为它已被编辑),emacs 没有缩进警卫(我什至不能制表),事实上我的警卫是与: rova​​rspra​​k - 这就是我收到解析错误的原因吗?而不是“cocboba”@Willem Van Onsem
    • “最终优化”完全不会做任何事情。 GHC 总是 重新排列模式以匹配构造函数的定义 顺序。是的,这有时很不幸,但目前就是这样。
    • @dfeuer:谁说使用 ghc?我可以构建自己的非智能 Haskell 编译器。与往常一样,您可以依靠编译器来查看优化,但最好自己执行一些优化(尽管过早的优化是一些邪恶的根源;)。
    • 好吧,这只是 emacs 的一些小错误。无论如何,谢谢,我只是从头开始学习haskell,所以我会更仔细地阅读你的其他建议
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 2020-12-14
    • 2012-10-31
    • 2013-08-12
    • 2022-01-21
    • 2011-04-09
    • 1970-01-01
    相关资源
    最近更新 更多