私は、テキストメニューを扱うためのコンソールプログラムを作っています。私は可能なメニューの選択肢の文字列を返す関数choices
と、ユーザによって入力された文字列をメニュー項目に変換する関数parseChoice
を持つクラスMenu
を書きました。Haskell - あいまいなクラス関数
data MainMenu = FirstItem | SecondItem
class Menu a where
choices :: String -- ERROR HERE
parseChoice :: String -> Maybe a
instance Menu MainMenu where
choices = "1) first choice\n2) second choice"
parseChoice "1" = Just FirstItem
parseChoice "2" = Just SecondItem
parseChoice _ = Nothing
getMenuItem :: Menu a => IO a
getMenuItem = do
putStrLn choices -- ERROR HERE
choice <- getLine
case parseChoice choice of
Just item -> return item
Nothing -> getMenuItem
main :: IO()
main = (getMenuItem :: IO MainMenu) >> return()
生憎、私はエラー
• Could not deduce (Menu a0) arising from a use of ‘choices’
from the context: Menu a
bound by the type signature for:
getMenuItem :: Menu a => IO a
at [removed].hs:15:1-29
The type variable ‘a0’ is ambiguous
These potential instance exist:
instance Menu MainMenu
-- Defined at [removed].hs:9:10
• In the first argument of ‘putStrLn’, namely ‘choices’
In a stmt of a 'do' block: putStrLn choices
In the expression:
do { putStrLn choices;
choice <- getLine;
case parseChoice choice of {
Just item -> return item
Nothing -> getMenuItem } }
次取得しています私は、Haskellはchoices
機能を使用することを知らないため、エラーが発生した知っています。私はputStrLn (choices :: Menu a)
のようなものを試しましたが、成功しませんでした。
質問:問題はどこで解決できますか?私は別のアプローチを使うべきですか?
そして、私はハスケル初心者です。
ありがとうございます。
短い答え:typeclassメソッドは引数または戻り値のいずれかの型を持たなければならないので、現在のデザインは 'choices :: String'で動作しません。その理由は、コンパイラは使用されている場所に基づいて型クラスを選択する方法がないからです。あなたは別のデザインを使用する必要がありますが、私は今すぐに思いつく時間がありません:) – porges