1
guessOneToTen :: IO()
guessOneToTen =
forever (do
number <- newNumber
guessed <- firstPrompt
untilM (== number) (const prompt) guessed
correct)
where
newNumber = newStdGen >>= randomR (1, 10) >>= return . fst
readLine = getLine >>= return . read
firstPrompt = putStr "Guess what number I am thinking of: " >> readLine
prompt = putStr "Sorry try again: " >> readLine
correct = putStrLn "You guessed correct!"
untilM :: (Monad m) => (a -> Bool) -> (a -> m a) -> a
untilM p f x
| p x = return()
| otherwise = f x >>= untilM p f
これは私が理由を理解していないGHCはIO時に再帰に問題がありますか?
baby.hs:804:43:
Occurs check: cannot construct the infinite type: t0 = t0 -> IO a0
In the third argument of `untilM', namely `guessed'
In a stmt of a 'do' expression:
untilM (== number) (const prompt) guessed
In the first argument of `forever', namely
`(do { number <- newNumber;
guessed <- firstPrompt;
untilM (== number) (const prompt) guessed;
correct })'
baby.hs:807:35:
Couldn't match expected type `IO a0'
with actual type `(a1, StdGen)'
Expected type: StdGen -> IO a0
Actual type: StdGen -> (a1, StdGen)
In the return type of a call of `randomR'
In the second argument of `(>>=)', namely `randomR (1, 10)'
baby.hs:813:9:
Couldn't match type `a' with `a -> m()'
`a' is a rigid type variable bound by
the type signature for
untilM :: Monad m => (a -> Bool) -> (a -> m a) -> a
at baby.hs:813:9
The equation(s) for `untilM' have three arguments,
but its type `(a -> Bool) -> (a -> m a) -> a' has only two
In an equation for `guessOneToTen':
guessOneToTen
= forever
(do { number <- newNumber;
guessed <- firstPrompt;
untilM (== number) (const prompt) guessed;
correct })
where
newNumber = newStdGen >>= randomR (1, 10) >>= return . fst
readLine = getLine >>= return . read
firstPrompt
= putStr "Guess what number I am thinking of: " >> readLine
prompt = putStr "Sorry try again: " >> readLine
....
baby.hs:815:42:
Couldn't match type `a' with `a -> m()'
`a' is a rigid type variable bound by
the type signature for
untilM :: Monad m => (a -> Bool) -> (a -> m a) -> a
at baby.hs:813:9
Expected type: (a -> m()) -> Bool
Actual type: a -> Bool
In the first argument of `untilM', namely `p'
In the second argument of `(>>=)', namely `untilM p f'
baby.hs:815:44:
Couldn't match type `a' with `a -> m()'
`a' is a rigid type variable bound by
the type signature for
untilM :: Monad m => (a -> Bool) -> (a -> m a) -> a
at baby.hs:813:9
Expected type: (a -> m()) -> m (a -> m())
Actual type: a -> m a
In the second argument of `untilM', namely `f'
In the second argument of `(>>=)', namely `untilM p f'
baby.hs:815:44:
Couldn't match type `a' with `a -> m()'
`a' is a rigid type variable bound by
the type signature for
untilM :: Monad m => (a -> Bool) -> (a -> m a) -> a
at baby.hs:813:9
Expected type: (a -> m()) -> m (a -> m())
Actual type: a -> m a
In the second argument of `untilM', namely `f'
In the second argument of `(>>=)', namely `untilM p f'
で失敗します。誰か光を当てることはできますか?
私は3つの変更を加えました。今は魅力のように機能します。 –