[Haskell-beginners] Maybe Return?
Ramnath R Iyer
rri at silentyak.com
Sun Jul 31 21:17:09 UTC 2016
Hi Francesco,
Thank you for your response, it definitely helped. Below is an updated
version of working code. Where I was getting tripped up earlier was in the
commented portion below. Also, if you scroll down further, I have a few
further questions. Thank you for your time.
module Main where
import Evaluator
import System.Console.Haskeline
main :: IO ()
main = runInputT defaultSettings loop
where
loop :: InputT IO ()
loop = do
line <- getInputLine ">> "
case line of
Nothing -> return ()
Just input -> do
let (result, next) = evaluate input
if (next == Return)
then return ()
else (emit result >> loop) -- I had wanted the result to be
emitted only on Continue, not Return. This works, but is it a good way?
emit :: Maybe String -> InputT IO ()
emit Nothing = return ()
emit (Just value) = outputStrLn $ "Executing: " ++ value
module Evaluator where
data Next = Continue | Return
deriving (Eq, Ord)
evaluate :: String -> (Maybe String, Next) -- Now updated to make the
first part of the tuple a Maybe String instead of String
evaluate "quit" = (Nothing, Return)
evaluate value = (Just value, Continue)
** QUESTIONS **
1. If I wanted to write the logic encapsulated in `emit' directly within
main, how would I do that? In my example, I was forced to extract it out as
a separate method specifically to leverage pattern matching.
2. You mentioned outputStrLn has a type `String -> InputT IO ()'. How do
you logically come to this conclusion? Is it because outputStrLn was taking
a single String argument and had to return the same type returned by loop
declared previously?
3. Are there better/simpler/more idiomatic ways of structuring my program?
On Sun, Jul 31, 2016 at 12:01 PM Francesco Ariis <fa-ml at ariis.it> wrote:
> On Sun, Jul 31, 2016 at 06:44:14PM +0000, Ramnath R Iyer wrote:
> > The program below is what I have working right now (very trivial). I want
> > to modify this program, so that the `evaluate input` returns not a
> String,
> > but a type X that includes information on whether to "continue" and show
> a
> > prompt after rendering the result, or exit altogether. So the specific
> > questions I have here are:
> >
> > 1. What would be a sensible type signature for X?
>
> Hello Ramnath,
>
> as now evaluate *has to* return a String because you pass its output as
> an argument to outputStrLn (which has a ~ `String -> InputT IO ()`
> signature itself).
>
> A quick hack is for `evaluate` to return
>
> evaluate :: String -> (String, Bool)
>
> where the Bool stands for 'should I exit or not' (using a datatype
> and/or a type synonym would be better and more clear).
> You can then write
>
> let (s, b) = evaluate input
> outputStrLn $ "Something " ++ s
> if b then loop
> else exit
>
> Your code has a very distinct imperative flavour (there are ways
> to get rid of that case/if cascade), but my opinion
> is: first make it work, then make it pretty.
>
> Does that help?
> -F
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160731/5b1442e4/attachment.html>
More information about the Beginners
mailing list