Ich mache ein Konsolenprogramm, in dem ich mit Textmenüs arbeiten werde. Ich schrieb eine Klasse Menu
mit der Funktion choices
, die eine Reihe von möglichen Menüoptionen und die Funktion parseChoice
zurückgibt, die die vom Benutzer eingegebene Zeichenfolge in den Menüpunkt umwandeln.Haskell - mehrdeutige Klassenfunktion
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()
Unfortunatelly, erhalte ich folgende Fehler
• 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 } }
Ich weiß, dass der Fehler tritt auf, weil Haskell wissen nicht, welche choices
Funktion verwenden. Ich habe etwas wie putStrLn (choices :: Menu a)
versucht, aber ohne Erfolg.
Fragen sind: Wo ist das Problem (und wie es zu beheben)? Sollte ich einen anderen Ansatz verwenden (was)?
Und bitte sei höflich, ich bin Haskell-Neuling.
Vielen Dank.
Kurzantwort: Typklassenmethoden müssen den Typ entweder in einem Argument oder einem Rückgabetyp haben, so dass Ihr aktuelles Design mit 'choices :: String' nicht funktionieren kann. Der Grund dafür ist, dass der Compiler keine Möglichkeit hat, die Typklasse basierend darauf auszuwählen, wo sie verwendet wird. Sie müssen ein alternatives Design verwenden, aber ich habe keine Zeit, um jetzt eine zu finden :) – porges