Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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
Debugging Haskell置换函数不编译_Debugging_Haskell_Types_Compiler Errors_Permutation - Fatal编程技术网

Debugging Haskell置换函数不编译

Debugging Haskell置换函数不编译,debugging,haskell,types,compiler-errors,permutation,Debugging,Haskell,Types,Compiler Errors,Permutation,我正在复习一些Haskell,我正在尝试编写一个置换函数,它将映射[1,2,3]>[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]。我有以下几点- permute:: [a] -> [[a]] permute [] = [] permute list = map f list where f x = listProduct x (permute (exclude x list))

我正在复习一些Haskell,我正在尝试编写一个置换函数,它将映射[1,2,3]>[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]。我有以下几点-

permute:: [a] -> [[a]]
permute [] = []
permute list = map f list
        where
                f x = listProduct x (permute (exclude x list))
                exclude e list1 = filter (/= e) list1
                listProduct x list2 = map (x :) list2
下面是我收到的错误消息-

permutations.hs:3:20:
    Couldn't match type `a' with `[a]'
      `a' is a rigid type variable bound by
          the type signature for permute :: [a] -> [[a]]
          at permutations.hs:1:11
    Expected type: a -> [a]
      Actual type: a -> [[a]]
    In the first argument of `map', namely `f'
    In the expression: map f list
    In an equation for `permute':
        permute list
          = map f list
          where
              f x = listProduct x (permute (exclude x list))
              exclude e list1 = filter (/= e) list1
              listProduct x list2 = map (x :) list2
Failed, modules loaded: none.

我会尝试调试,但它甚至无法编译。有什么想法吗?

让我们只关注涉及的列表类型:

permute (exclude x list)
类型为
[[a]]
,因为类型签名为
permute
,因此

listProduct x (permute (exclude x list))
def的类型也是
[[a]]
。属于
listProduct

listProduct x list2 = map (x :) list2
综上所述,

 f x = listProduct x (permute (exclude x list))
返回
[[a]]
,但是

permute list = map f list
f
应用于
[a]
的所有元素,返回一个
[[a]]]]
, 这不是
permute
的正确返回类型

如何修复
  • 通过连接所有列表,将
    [[a]]]
    转换为
    [[a]]]
  • 添加一个
    Eq a
    约束,因为您在
    exclude
    中使用了
    /=x
  • 基本情况目前表明空列表没有排列,这是错误的。
    []
    有一个排列。(事实上,0!=1,而不是0)

  • 对任何可能感兴趣的人来说——为了解决这个问题,我需要一种方法来模拟命令式编程的迭代,因此,一个循环列表建议了它自己(本质上,我一直在尝试模拟我曾经用javascript编写的解决方案,该解决方案涉及我描述的相同过程,唯一的例外是我利用了for循环)

    permute[]=[]]
    排列列表=[h:tail | h这样做的“正确”方法是将列表项的拾取和排除合并到一个纯粹的位置操作中
    select::[a]->[(a[a])]

    顺便说一句,如果您不自己指定类型签名,它将编译并向您报告
    [a]->[[[a]]]]
    类型


    更重要的是,通过将
    /=
    引入到图片中,您不需要对列表中的项进行
    Eq a
    约束:
    permute::(Eq a)=>[a]->[[a]]

    它在某种程度上为您调试,说它期望
    f
    是类型a->[a]的函数,但得到的是类型a->[[a]]
    listProduct
    任何东西看起来都应该返回一个
    [[a]]
    ,这将使
    f
    接受参数
    x
    ,并返回一个
    [[a]]
    。或许可以尝试独立地对每个函数进行实验,以确保它执行您希望它执行的操作。吉拉德,为什么f应该是(a->[a]类型?根据map的定义,似乎f有权映射到完全多态类型-
    map::(a->b)->[a]->[b]map f[]=[]map f(x:xs)=f x:map f xs
    您应该在
    f
    exclude
    listProduct
    上放置类型签名。当您有类型签名时,编译器错误将为您提供更多关于错误位置的线索。@criticalImperitive通常是一个好主意,尽管在这种特殊情况下需要
    ScopedTypeVariables
    扩展,实际上没有任何帮助。嘿,所以我不确定我是否同意最后的评论。我们将
    f
    应用于
    列表中的每个元素,而不是
    列表作为一个整体;也就是说,我们将
    f
    应用于
    a
    类型的值,而不是
    [a]
    。至少这是我的意图。因此我们应该返回
    [[a]]
    ,而不是
    [[a]]]
    @DanSok,如果
    f
    列表的每个元素返回
    [[a]]
    ,则
    映射f列表的结果是
    [[a]]
    permute [] = [[]]
    permute list = [h:tail | h <- list, tail <- (permute (exclude h list))]
      where
        exclude x = filter (/= x)
    
    import Control.Arrow (second)
    -- second f (a, b) = (a, f b)
    
    select [] = []
    select (x:xs) = (x,xs) : map (second (x:)) (select xs)
    
    permute [] = [[]]    -- 1 permutation of an empty list
    permute xs = [x : t | (x,rest) <- select xs, t <- permute rest] 
    
    > let exclude e list1 = filter (/= e) list1
    > let listProduct x list2 = map (x :) list2
    > let f x = listProduct x (permute (exclude x list)) 
    <interactive>:1:25: Not in scope: `permute' -- permute is not defined yet!!
    <interactive>:1:44: Not in scope: `list'    -- need to pass 'list' in
    > let f list x = listProduct x (undefined (exclude x list))
                                    ---------   -- use a stand-in for now
    > let permute [] = [] ; permute list = map (f list) list
    > :t permute                           ---
    permute :: (Eq t) => [t] -> [[[t]]]    -- one too many levels of list!
    
    > let permute [] = [] ; permute list = concatMap (f list) list
    > :t permute                           ---------
    permute :: (Eq t) => [t] -> [[t]]      -- much better