Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops Haskell堆栈实现_Loops_Haskell_Stack - Fatal编程技术网

Loops Haskell堆栈实现

Loops Haskell堆栈实现,loops,haskell,stack,Loops,Haskell,Stack,这是我第一次在StackOverflow上发帖。我正在学习Haskell,并试图制作一个操作堆栈的函数test。它将整数列表作为输入,然后执行以下操作: 如果数字为偶数: 如果数字是24,并且在当前索引之前的输入列表中没有出现2,那么我们抛出一个错误 否则,我们将数字推送到堆栈中 例如,list=[0,1,2,3,4,24]。列表中出现了2,因此我们将24推到堆栈中 如果数字为奇数: 如果堆栈顶部==当前数字-1,则从堆栈中弹出。否则,我们抛出一个错误 如果弹出堆栈后堆栈为空,我们将显示

这是我第一次在StackOverflow上发帖。我正在学习Haskell,并试图制作一个操作堆栈的函数
test
。它将整数列表作为输入,然后执行以下操作:

  • 如果数字为偶数:
    • 如果数字是24,并且在当前索引之前的输入列表中没有出现2,那么我们抛出一个错误
    • 否则,我们将数字推送到堆栈中
    • 例如,
      list=[0,1,2,3,4,24]
      。列表中出现了2,因此我们将24推到堆栈中
  • 如果数字为奇数:
    • 如果堆栈顶部==当前数字-1,则从堆栈中弹出。否则,我们抛出一个错误
    • 如果弹出堆栈后堆栈为空,我们将显示一条“成功”消息
  • 目前,我已经成功实现了堆栈,我认为
    push
    pop
    peek
    操作具有
    O(1)
    复杂性,但我相信一定有更好的实现方法:

    emptyStack :: [a]
    emptyStack = []
    
    push :: a -> [a] -> [a]
    push item xs = item : xs
    
    pop :: [a] -> [a]
    pop [] = error "Cannot pop from empty stack."
    pop xs = tail xs
    
    peek :: [a] -> a
    peek = head
    
    对于
    test
    函数,这就是我提出的这个怪物,它不会在列表中迭代,而且
    stack=emptyStack
    没有意义:

    test :: Integral a => [a] -> Either String [a]
    test [] = Left "Empty input list"
    test (x:xs) | even x = if x == 24 && notElem 2 (x:xs) then Left "Error!"
                            else Right (push x stack)
                | odd x = if null (Right (pop xs)) then Left "Success~" else
                            (if peek stack == x - 1 then Right (pop stack)
                            else Left "Not 1 less than current number!")
        where stack = emptyStack
    

    我的
    测试
    实现应该如何修改以满足开头提到的要求?提前谢谢

    另一种可能的方法是:不要硬连接堆栈。使函数同时接受堆栈和指令列表,并返回修改后的堆栈和修改后的指令列表(或错误)。小心不要将堆栈与指令列表混淆,因为它们的类型完全相同。也许您可以先专注于执行一个步骤,然后将您的解决方案扩展到使用整个指令列表的解决方案代码有问题:
    上的
    null
    对于
    值,其中一个
    始终为
    ,对于
    值,始终为
    。(为什么
    null
    一起工作?
    这是一个很长的故事,它涉及到一种叫做
    可折叠的
    )您总是将null与
    值一起使用。也许你的意思不同,比如直接检查
    popxs
    是否为空?通常,对列表执行模式匹配(
    case pop xs of[]->..z:zs->..
    )是检测列表是否为空的更好方法。@danidiaz感谢您的回复!关于您的第一条注释,我的意思是函数应该在从堆栈中弹出一个元素后立即检查堆栈是否为空,因此我使用了
    Right(popxs)
    。关于第二条评论,你能告诉我你所说的“说明清单”是什么意思吗?这是指开始时的需求,还是指整数的输入列表?是的,我指的是整数列表。我仍然不明白为什么要使用
    Right(popxs)
    。您正在计算
    popxs
    ,将其包装在
    右侧
    ,并对其调用
    null
    。为什么要添加右侧的
    ?您可以在ghci中尝试键入类似于
    null(右([]::[Int])
    null(右[1::Int,2])
    的内容。您将看到它总是返回
    False
    @danidiaz我试图匹配函数的类型签名,因此我加入了
    Right
    来匹配
    字符串[Int]
    。但是现在我明白你的观点了,事实上没有理由在那里添加
    右边的