Похоже, вам просто нужно привязать значение, возвращаемое в монаде из start
, например:
main = do
putStrLn "Welcome."
let start startMessage = do
putStrLn startMessage
let ask message = do
putStrLn message
choice <- getLine
either ask return $ userChoice(choice)
ask $ "What would you like to do?\n" ++ displayOptions(0)
-- THE NEW BIT I ADDED:
opt <- start "Choose a number between 1-4."
putStrLn opt -- THIS PRINTS "You proceed with ..."
-- SNIP
Вы можете прочитать о "desugaring do
нотации", чтобы узнать, как это переводится на лямбды и методы класса Monad
(>>=
и return
).
Пара других предложений:
Вы можете использовать (и должны предпочитать) сопоставление с образцом вместо охранников и ==
(метод класса Eq
, который реализуют не все типы). Э.Г.
userChoice2 option = case option of
"1" -> "You proceed with option 1."
"2" -> "You proceed with option 2"
Помните, что в haskell синтаксис для вызова foo
для a
и b
равен foo a b
, а не foo(a,b)
Может быть очень полезно включить предупреждения (как во время обучения, так и на основе производственного кода), например здесь я загружаю ваш файл в ghci после включения -Wall
:
Prelude> :set -Wall
Prelude> :l k.hs
[1 of 1] Compiling Main ( k.hs, interpreted )
k.hs:15:1: warning: [-Wmissing-signatures]
Top-level binding with no type signature: main :: IO b
|
15 | main = do
| ^^^^
k.hs:24:5: warning: [-Wunused-do-bind]
A do-notation statement discarded a result of type ‘String’
Suppress this warning by saying
‘_ <- start "Choose a number between 1-4."’
|
24 | start "Choose a number between 1-4."
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ok, one module loaded.
Обратите внимание, что предупреждает вас, что start
возвращает IO String
, но вы ничего не сделали со значением String
, что действительно было ошибкой. Если вы действительно хотите отказаться от значения, вы можете использовать void
, чтобы сделать его явным и отключить ошибку.