【问题标题】:Trying to iterate over a forest Haskell compilation error尝试遍历森林 Haskell 编译错误
【发布时间】:2014-12-11 14:29:30
【问题描述】:

我尝试为森林的每个节点分配一个编号,这样就不会有 2 个具有相同编号的节点。我尝试使用 2 个相互调用递归的函数,但我得到了一些编译错误。 这是代码:

numberTree :: Int -> Tree a -> (Tree Int,Int)

numberTree n (Node c []) = (Node n [], n+1)
numberTree n (Node _ (x:xs)) =  (Node n  fst.numberForest  (n+1) xs, snd.numberForest   (n+1) xs)


numberForest :: Int -> [Tree a] -> ([Tree Int],Int)

numberForest n (x:xs) = ((fst(numberTree n x )):(fst(numberForest (n+1) xs)), snd(numberForest (n+1) xs)+1)

numberForest n (x:xs) = ((fst(numberTree n x )):(fst(numberForest (n+1) xs)), snd(numberForest (n+1) xs)+1)

我得到的错误是:

.hs:27:34: 无法匹配预期类型 b0 -> c0' with actual typeTree Int 可能原因:Node' is applied to too many arguments In the first argument of(.)',即`Node n fst' 在表达式中:节点 n fst 。 numberForest (n + 1) xs

.hs:27:34:
Couldn't match expected type `Tree Int' with actual type `a0 -> c0
In the expression: Node n fst . numberForest (n + 1) xs
In the expression:
  (Node n fst . numberForest (n + 1) xs,
   snd . numberForest (n + 1) xs)
In an equation for `numberTree':
    numberTree n (Node _ (x : xs))
      = (Node n fst . numberForest (n + 1) xs,
         snd . numberForest (n + 1) xs)

 .hs:27:42:
Couldn't match type `(a1, b1) -> a1' with `[Tree Int]'
Expected type: Forest Int
  Actual type: (a1, b1) -> a1
Probable cause: `fst' is applied to too few arguments
In the second argument of `Node', namely `fst'
In the first argument of `(.)', namely `Node n fst'

 .hs:27:46:
Couldn't match expected type `a0 -> b0'
            with actual type `([Tree Int], Int)'
Possible cause: `numberForest' is applied to too many arguments
In the second argument of `(.)', namely `numberForest (n + 1) xs'
In the expression: Node n fst . numberForest (n + 1) xs

.hs:27:70:
Couldn't match expected type `Int' with actual type `a2 -> c1'
In the expression: snd . numberForest (n + 1) xs
In the expression:
  (Node n fst . numberForest (n + 1) xs,
   snd . numberForest (n + 1) xs)
In an equation for `numberTree':
    numberTree n (Node _ (x : xs))
      = (Node n fst . numberForest (n + 1) xs,
         snd . numberForest (n + 1) xs)

.hs:27:74:
Couldn't match expected type `a2 -> (a3, c1)'
            with actual type `([Tree Int], Int)'
Possible cause: `numberForest' is applied to too many arguments
In the second argument of `(.)', namely `numberForest (n + 1) xs'
In the expression: snd . numberForest (n + 1) xs

出了什么问题,我应该如何解决这个问题?

【问题讨论】:

  • 您应该包含Tree 类型的定义方式。
  • Node n fst . numberForest (n + 1) xs -> 也许这应该是Node n $ fst $ numberForest (n + 1) xs

标签: haskell compiler-errors tree parse-forest


【解决方案1】:

这一行

numberTree n (Node _ (x:xs)) =  (Node n  fst.numberForest  (n+1) xs, snd.numberForest   (n+1) xs)

其实就是

numberTree n (Node _ (x:xs)) =  ( (Node n fst) . (numberForest (n+1) xs)
                                , snd . (numberForest (n+1) xs))

它试图组合树而不是函数,导致编译器抱怨。你可能想要这样的东西:

numberTree n (Node _ (x:xs)) =  ( Node n  (fst (numberForest  (n+1) xs))
                                , snd (numberForest (n+1) xs))

但是,请注意上面的代码计算了两次numberForest (n+1) xs,导致指数级爆炸。您可以避免这种情况,例如如下使用let ... in ...

numberTree n (Node _ (x:xs)) =  let result = numberForest (n+1) xs
                                in (Node n (fst result), snd result)

您可以使用let 中的模式匹配进一步改进这一点:

numberTree n (Node _ (x:xs)) =  let (forest, n') = numberForest (n+1) xs
                                in (Node n forest, n')

【讨论】:

    【解决方案2】:

    state monad 是你的朋友。

    import Control.Monad.Trans.State
    
    data Tree   a = Node a (Forest a)
    type Forest a = [Tree a]
    
    numberTreeS :: Tree a -> State Int (Tree Int)
    numberTreeS (Node _ xs) = do
        n <- get
        put (n + 1)
        xs' <- numberForestS xs
        return $ Node n xs'
    
    numberForestS :: Forest a -> State Int (Forest Int)
    numberForestS = mapM numberTreeS
    
    numberForest :: Forest a -> Forest Int
    numberForest xs = evalState (numberForestS xs) 0
    

    这比显式状态传递更具可读性。

    【讨论】:

      猜你喜欢
      • 2018-10-05
      • 2023-03-24
      • 2016-07-20
      • 1970-01-01
      • 2021-07-01
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 2016-10-26
      相关资源
      最近更新 更多