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
Function 从函数列表中删除重复项_Function_Haskell_Duplicates - Fatal编程技术网

Function 从函数列表中删除重复项

Function 从函数列表中删除重复项,function,haskell,duplicates,Function,Haskell,Duplicates,是否可以从Haskell中的函数列表中删除重复项(如nub)? 基本上,是否可以为(Eq(Integer->Integer))添加一个实例 在ghci中: let fs = [(+2), (*2), (^2)] let cs = concat $ map subsequences $ permutations fs nub cs <interactive>:31:1: No instance for (Eq (Integer -> Integer)) arising fr

是否可以从Haskell中的函数列表中删除重复项(如nub)? 基本上,是否可以为(Eq(Integer->Integer))添加一个实例

在ghci中:

let fs = [(+2), (*2), (^2)]
let cs = concat $ map subsequences $ permutations fs
nub cs

<interactive>:31:1:
No instance for (Eq (Integer -> Integer))
  arising from a use of `nub'
Possible fix:
  add an instance declaration for (Eq (Integer -> Integer))
In the expression: nub cs
In an equation for `it': it = nub cs
为了得到这个

> css

[[],[AddTwo],[Double],[AddTwo,Double],[Square],[AddTwo,Square],[Double,Square],[AddTwo,Double,Square],[Double,AddTwo],[Double,AddTwo,Square],[Square,Double],[Square,AddTwo],[Square,Double,AddTwo],[Double,Square,AddTwo],[Square,AddTwo,Double],[AddTwo,Square,Double]]
然后这个

> map (\cs-> call <$> cs <*> [3,4]) css

[[],[5,6],[6,8],[5,6,6,8],[9,16],[5,6,9,16],[6,8,9,16],[5,6,6,8,9,16],[6,8,5,6],[6,8,5,6,9,16],[9,16,6,8],[9,16,5,6],[9,16,6,8,5,6],[6,8,9,16,5,6],[9,16,5,6,6,8],[5,6,9,16,6,8]]
>映射(\cs->调用cs[3,4])css
[[],[5,6],[6,8],[5,6,6,8],[9,16],[5,6,9,16],[6,8,9,16],[5,6,6,8,9,16],[6,8,5,6],[6,8,5,6,9,16],[9,16,6,8],[9,16,5,6],[9,16,6,8,5,6],[6,8,9,16,5,6],[9,16,5,6,6,8],[5,6,9,16,6,8]]

,这是我的初衷。

不,这是不可能的。不能比较函数是否相等

原因是:

  • 指针比较对于Haskell函数来说意义不大,因为从那时起,
    id
    \x->id x
    的相等性将根据后一种形式是否优化为
    id
    而改变
  • 函数的扩展比较是不可能的,因为它需要对停止问题有一个积极的解决方案(两个函数具有相同的停止行为是相等的必要条件)
  • 解决方法是将函数表示为数据:

    data Function = AddTwo | Double | Square deriving Eq
    
    call AddTwo  =  (+2)
    call Double  =  (*2)
    call Square  =  (^2)
    

    不,对于
    Integer->Integer
    函数不可能这样做

    但是,如果您还可以使用更通用的类型签名
    Num a=>a->a
    ,这是可能的,正如您的示例所示!一种天真的方式(不安全),会像

    {-# LANGUAGE FlexibleInstances           #-}
    {-# LANGUAGE NoMonomorphismRestriction   #-}
    
    data NumResLog a = NRL { runNumRes :: a, runNumResLog :: String }
                 deriving (Eq, Show)
    
    instance (Num a) => Num (NumResLog a) where
      fromInteger n = NRL (fromInteger n) (show n)
      NRL a alog + NRL b blog
                = NRL (a+b) ( "("++alog++ ")+(" ++blog++")" )
      NRL a alog * NRL b blog
                = NRL (a*b) ( "("++alog++ ")*(" ++blog++")" )
      ...
    
    
    instance (Num a) => Eq (NumResLog a -> NumResLog a) where
      f == g  = runNumResLog (f arg) == runNumResLog (g arg)
         where arg = NRL 0 "THE ARGUMENT"
    
    unlogNumFn :: (NumResLog a -> NumResLog c) -> (a->c)
    unlogNumFn f = runNumRes . f . (`NRL`"")
    
    这基本上是通过比较函数源代码的“标准化”版本来实现的。当然,当您比较例如
    (+1)==(1+)
    时,这是失败的,它们在数值上是相等的,但产生
    “(参数)+(1)”
    “(1)+(参数)”
    ,因此被指示为不相等。然而,由于函数
    Num a=>a->a
    本质上被压缩为多项式(是的,
    abs
    signum
    使其变得有点困难,但仍然可行),您可以找到一种数据类型来正确处理这些等价关系

    这些材料可以这样使用:

    > let fs = [(+2), (*2), (^2)]
    > let cs = concat $ map subsequences $ permutations fs
    > let ncs = map (map unlogNumFn) $ nub cs
    > map (map ($ 1)) ncs
    [[],[3],[2],[3,2],[1],[3,1],[2,1],[3,2,1],[2,3],[2,3,1],[1,2],[1,3],[1,2,3],[2,1,3],[1,3,2],[3,1,2]]
    
    > let fs = [(+2), (*2), (^2)]
    > let cs = concat $ map subsequences $ permutations fs
    > let ncs = map (map unlogNumFn) $ nub cs
    > map (map ($ 1)) ncs
    [[],[3],[2],[3,2],[1],[3,1],[2,1],[3,2,1],[2,3],[2,3,1],[1,2],[1,3],[1,2,3],[2,1,3],[1,3,2],[3,1,2]]