作为haskell的新手,我决定尝试并实现一个迷你反向波兰符号功能:
接受类型为list的int和字符串运算符('*','+','/','-')
将运算符应用于tail元素和tail-1元素
返回包含在操作中的两个元素的结果list,并以这样的方式将结果元素附加到尾部:
Where e0 = original element at index 0
r = result of the operation:
result = [e0,e1,e2...r] (elements popped off: eN, eN-1)这是我到目前为止掌握的代码:
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它给出了以下编译错误:
• 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) "/"我相信这是一个错误的结果在我的语法,任何帮助都欢迎!
发布于 2018-11-30 22:54:42
您已经正确地实现了该函数,但是语法稍有错误--当您想要使用模式匹配时使用了保护:
Bool类型的有效表达式。)在您的代码中,您使用了保护程序,但是您确实需要模式匹配,如下所示:
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但是,这仍然会产生一个错误:
* 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),如果您想要引用stack和operator来获取类似于错误消息的内容。
编辑:在@chepner下面的注释中建议了使用模式匹配和保护的另一种方法:
step :: [Int] -> String -> [Int]
step (x:y:ys) op
| op == "*" = (x * y):ys
| op == "+" = (x + y):ys
-- etc.
| otherwise = (some error case)这再次说明了两者之间的区别:模式匹配用于将第一个参数分解为x、y和ys,而守护则使用布尔条件( otherwise实际上在前奏中被定义为等于True)。
https://stackoverflow.com/questions/53565866
复制相似问题