首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >haskell反向抛光符号

haskell反向抛光符号
EN

Stack Overflow用户
提问于 2018-11-30 22:40:10
回答 1查看 1.3K关注 0票数 2

作为haskell的新手,我决定尝试并实现一个迷你反向波兰符号功能:

接受类型为listint和字符串运算符('*','+','/','-')

将运算符应用于tail元素和tail-1元素

返回包含在操作中的两个元素的结果list,并以这样的方式将结果元素附加到尾部:

代码语言:javascript
复制
Where e0 = original element at index 0

r = result of the operation:

result = [e0,e1,e2...r] (elements popped off: eN, eN-1)

这是我到目前为止掌握的代码:

代码语言:javascript
复制
import Data.List
import System.IO

step :: [Int] -> String -> [Int]
step stack operator
    | (x:y:ys) "*" = (x * y):ys
    | (x:y:ys) "+" = (x + y):ys
    | (x:y:ys) "-" = (x - y):ys
    | (x:y:ys) "/" = (x / y):ys

它给出了以下编译错误:

代码语言:javascript
复制
• Couldn't match expected type ‘[Char] -> Bool’
                  with actual type ‘[a3]’
    • The function ‘x : y : ys’ is applied to one argument,
      but its type ‘[a3]’ has none
      In the expression: (x : y : ys) "/"
      In a stmt of a pattern guard for
                     an equation for ‘step’:
        (x : y : ys) "/"

我相信这是一个错误的结果在我的语法,任何帮助都欢迎!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-30 22:54:42

您已经正确地实现了该函数,但是语法稍有错误--当您想要使用模式匹配时使用了保护:

  • 当您想将一个参数分解成较小的部分或在一些情况下处理它时,就会使用模式匹配;
  • 当您想要基于布尔条件选择函数的一个分支时,就会使用保护措施,类似于if/if/ one表达式。(因此,保护的条件必须是Bool类型的有效表达式。)

在您的代码中,您使用了保护程序,但是您确实需要模式匹配,如下所示:

代码语言:javascript
复制
step :: [Int] -> String -> [Int]
step (x:y:ys) "*" = (x * y):ys
step (x:y:ys) "+" = (x + y):ys
step (x:y:ys) "-" = (x - y):ys
step (x:y:ys) "/" = (x / y):ys

但是,这仍然会产生一个错误:

代码语言:javascript
复制
* No instance for (Fractional Int) arising from a use of `/'
* In the first argument of `(:)', namely `(x / y)'
  In the expression: (x / y) : ys
  In an equation for `step': step (x : y : ys) "/" = (x / y) : ys

这个错误是相当清楚的:您试图/一个整数,但整数不是Fractional,所以您不能这样做。如果需要整数除法,可以用div x y替换它,否则可以在类型签名中将Int更改为Float,以允许非整数值。

然而,即使在进行此更改之后,仍然存在一个微妙的错误:如果列表中的元素少于两个,或者使用了一个不受支持的运算符,会发生什么?这里要做的正确的事情是使用step _ _ = (something)进行模式匹配,其中_是一种特殊的语法,可以匹配任何内容。(或者您也可以使用step stack operator = (something),如果您想要引用stackoperator来获取类似于错误消息的内容。

编辑:在@chepner下面的注释中建议了使用模式匹配和保护的另一种方法:

代码语言:javascript
复制
step :: [Int] -> String -> [Int]
step (x:y:ys) op
    | op == "*" = (x * y):ys
    | op == "+" = (x + y):ys
    -- etc.
    | otherwise = (some error case)

这再次说明了两者之间的区别:模式匹配用于将第一个参数分解为xyys,而守护则使用布尔条件( otherwise实际上在前奏中被定义为等于True)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53565866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档