3

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

前もって感謝します。

...

さらに、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]]

、それが私の当初の意図でした。

4

2 に答える 2

3

いいえ、Integer -> Integer関数に対してこれを行うことはできません。

ただし、に、より一般的なタイプの署名でも問題ない場合Num a => a -> a可能です! 1つの単純な方法(安全ではない)は、次のようになります

{-# 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->aabssignum

ものは次のように使用できます。

> 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]]
于 2013-04-20T10:11:11.380 に答える