是否可以从Haskell中的函数列表中删除重复项(如nub中)? 基本上,是否可以为(Eq(整数 - >整数))
添加实例在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
提前致谢。
...
此外,根据larsmans的回答,我现在能够做到这一点
> let fs = [AddTwo, Double, Square]
> let css = nub $ concat $ map subsequences $ permutations fs
为了得到这个
> 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]]
,这是我最初的意图。
答案 0 :(得分:8)
不,这是不可能的。无法比较函数的相等性。
原因是:
id
和\x -> id x
的相等性会根据后一种形式是否被优化为id
而发生变化。解决方法是将函数表示为数据:
data Function = AddTwo | Double | Square deriving Eq
call AddTwo = (+2)
call Double = (*2)
call Square = (^2)
答案 1 :(得分:3)
不,不可能为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+)
,它在数字上等效但是"(THE ARGUMENT)+(1)"
与"(1)+(THE ARGUMENT)"
相比,因此表示为不相等。但是,由于函数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]]