1

次のコードは、次のような入力に非常に適しています。

*Main> eval 'y' (21 :: Int)
42
*Main> eval 'x' 'a'
42
*Main> eval (21 :: Int) (21 :: Int)
42
*Main> eval (42 :: Int) 'a'
42

この背後にある一般的な問題は、2つのことを追加したいということです。sに追加することIntは、実現するのは難しくありません(すでに組み込まれています)。しかし、私はsをsgetiに解決する特定の関数(ここ)を持っており、私の関数は2つのsを追加し、 (すべての順列で)と組み合わせる必要があります。sは、関数によってsに変換され、追加できるようになります。私は次のような他の解決策について考えました:CharIntaddIntIntCharChargetiInt

eval (geti 'a') (42 :: Int)

しかし、それは私には不可能です。

したがって、一般的に私の質問は、これをより単純にする、またはよりエレガントに実装する方法はありますか?

これはコードです:

-- A static function only used to resolve some demo data
geti :: Char -> Int
geti c | c == 'x' = 42
       | c == 'y' = 21
       | c == 'z' = 10
       | otherwise = 0


-- Here comes the problem:
class Eval t1 t2 where 
    eval :: t1 -> t2 -> Int

instance Eval Int Int where
    eval a b = a + b

instance Eval Int Char where
    eval a c = a + (geti c)

instance Eval Char Int where
    eval c b = (geti c) + b

instance Eval Char Char where
    eval c1 c2 = (geti c1) + (geti c2)

PS:私はまた、ここからのソリューションを「汎用」(はい、Java言語ですが、Haskellは初めてです... sry)関数と組み合わせようとしましたが、それは機能しませんでした...

4

1 に答える 1

7

「に変換できる」の型クラスを作成し、Intそれを使用して実装する方が簡単だと思いevalます。

class Intable a where
   intify :: a -> Int

instance Intable Int where
   intify = id

instance Intable Char where
   intify = geti


eval :: (Intable a, Intable b) => a -> b -> Int
eval a b = intify a + intify b
于 2013-01-13T17:11:37.967 に答える