Goo
たとえば、C++、Java、C# などの言語で同等のインターフェイスであると主張されることが多い、私の型クラスを考えてみましょう。
class Goo goo where ham :: goo -> String
data Hoo = Hoo
instance Goo Hoo where ham _ = "Hoo!"
mustard _ = "Oh oh."
data Yoo = Yoo
instance Goo Yoo where ham _ = "Yoo!"
mustard _ = "Whew"
しかし、私は返すことができませんGoo
:
paak :: (Goo goo) => String -> goo
paak g = (Yoo)
-- Could not deduce (goo ~ Yoo)
-- from the context (Goo goo)
-- bound by the type signature for paak :: Goo goo => String -> goo
-- at frob.hs:13:1-14
-- `goo' is a rigid type variable bound by
-- the type signature for paak :: Goo goo => String -> goo
-- at frob.hs:13:1
-- In the expression: (Yoo)
-- In an equation for `paak': paak g = (Yoo)
この啓発的な声明を見つけました。これは、その理由を説明しています。
型
paak :: (Goo goo) => String -> goo
は、関数が必要なものを返す可能性があることを意味するものではありませんGoo
。Goo
これは、関数がユーザーが望むものを返すことを意味します。
(ここでsepp2kの回答から音訳)
しかし、では、Goo
制約を満たすが、、、、またはその他の何かを返すまたは保存するにはどうすればよいでしょうか?Hoo
Yoo
Moo
Boo
Goo
私は自分のプログラミングのバックグラウンドに巻き込まれすぎて、C のようなインターフェイスに頼るなど、まったく別の考え方をする必要があるのでしょうか。
data WhewIamAGoo = WhewIamAGoo {
ham' :: String
mustard' :: String
}
paak :: String -> WhewIamAGoo
paak g = let yoo = Yoo
in WhewIamAGoo { ham' = ham yoo
mustard' = mustard ham
}
しかし、それは厄介なようです。
私の特定のケースでは、次のように使用したいと思いGoo
ます。
let x = someGoo ....
in ham x ++ mustard x
Yoo
つまり、呼び出し元はすべてのs などについて知る必要はありません。
編集:明確にするために:Haskellプログラマーがそのような状況に陥る方法を探しています。慣用的な方法でそれをどのように処理しますか?