3

次のプログラムは、型チェックとコンパイルを行います。

import Control.Arrow

data Ns = Na | Nb | Nc | Nd deriving Show

data Net a where
    Uni :: a -> Net a
    Serial :: Net a -> Net a -> Net a
    Branch :: Show a => Net a -> Net (Net a, Net a)

deriving instance Show a => Show (Net a)

eval :: (Arrow a) => Net c -> a b (Net c)
eval (Uni m) = arr (const (Uni m))
eval (Serial m n) = eval m >>> eval n
--eval (Branch m) = eval m &&& eval m

example = Serial (Serial (Uni Na) (Uni Nb)) (Serial (Uni Nc) (Uni Nd))

main = do
    putStrLn $ show (app (eval example, Na))

ただし、 のケースを追加しようとするとeval (Branch m)、checking bombs out と入力します。タイプの何か

Arrow a => a b (Net d)

が期待されていますが、もちろん私が持っている方法は

Arrow a => a b (c',c'')

書き方について誰か提案がありますeval (Branch m)か?

編集私

@sabauma のコメントに応えて、 の型シグネチャevalを変更する必要があると思いますが、どうすればよいかわかりません。

編集Ⅱ

何が起こるべきかの例を次に示します。

branch = Branch example
app (eval branch, Na)

与えるべき、

Uni (Uni Na,Uni Na)

これが @sabauma さんの提案です。

4

3 に答える 3

3

1つの可能性は

eval :: (Arrow a) => Net c -> a b (Net c)
eval (Uni m)      = arr (const (Uni m))
eval (Serial m n) = eval m >>> eval n
eval (Branch m)   = (eval m &&& eval m) >>> arr Uni

これが望ましい動作をしているかどうかはわかりませんが、型チェックを行い、簡単な解決策ではありません。これにより、型シグネチャを変更せずに逃げることができます。

于 2013-03-13T14:39:35.510 に答える
3

私の推測では、Branch2 つの引数を取るように再定義することになります (分岐は何らかの形で私にとってそれを意味するため)。

data Net a where
  Uni :: a -> Net a
  Serial :: Net a -> Net a -> Net a
  Branch :: Show a => Net a -> Net a -> Net (Net a, Net a)

につながる

eval :: (Arrow a) => Net c -> a b (Net c)
eval (Uni m) = arr (const $ Uni m)
eval (Serial m n) = eval m >>> eval n
eval (Branch l r) = (eval l) &&& (eval r) >>> arr (uncurry Branch)

しかし、この変更があなたにとって意味があるかどうかはわかりません。おそらく、あなたの型がどのように使われるかを説明する必要があります。

于 2013-03-13T14:51:52.880 に答える
2

あなたのコードの目的については完全にはわかりませんが、これはあなたが求めているものではないかもしれませんが、次の型チェック:

eval :: Arrow a => Net c -> a b (Net c)
eval (Uni m)      = arr (const (Uni m)) 
eval (Serial m n) = eval m >>> eval n
eval (Branch m)   = arr (const (Branch m)) 

もちろん、arr . consteval で自明に機能しますが、今では、それはあなたが望んでいたものではないとほぼ確信しています。

于 2013-03-13T14:18:43.670 に答える