How to create a 'do' block in Agda - agda

I have some code working in Haskell and I want to convert it into Agda.
This is the Haskell code
main = do
putStrLn "A string"
putStrLn "second string"
and the output is
A string
second string
I've tried converting it into Agda with
open import Common.IO
main = do
putStrLn "A string"
putStrLn "second string"
but I just get the error message
'_>>_ needs to be in scope to desugar 'do' block'
(a screenshot of the error in full: https://imgur.com/a/3lxdwR7)
Edit: This is my best guess, it obviously won't work, but I'm new to Agda... any ideas?
open import Common.IO
_>>_ : ? → ? → ?
??? = ???
??? = ???
main = do
putStrLn "A string"
putStrLn "second string"
... how do I get my code working in Agda?

I don't know what Common.IO is. Using the standard library, you can write:
open import IO
open import Codata.Musical.Notation
main = run do
♯ putStrLn "A string"
♯ putStrLn "second string"
The funny ♯_ is what we call musical notation: IO leads to potentially infinite computations so we have to use coinductive types.
Note however that IO in the standard library was created before do notations were added to Agda so if they're sort-of compatible it's only by accident. It's probably better to stick to >>= (and try to write pure code as soon as possible, only using IO at the boundaries).

Related

Parse String to Datatype in Haskell

I'm taking a Haskell course at school, and I have to define a Logical Proposition datatype in Haskell. Everything so far Works fine (definition and functions), and i've declared it as an instance of Ord, Eq and show. The problem comes when I'm required to define a program which interacts with the user: I have to parse the input from the user into my datatype:
type Var = String
data FProp = V Var
| No FProp
| Y FProp FProp
| O FProp FProp
| Si FProp FProp
| Sii FProp FProp
where the formula: ¬q ^ p would be: (Y (No (V "q")) (V "p"))
I've been researching, and found that I can declare my datatype as an instance of Read.
Is this advisable? If it is, can I get some help in order to define the parsing method?
Not a complete answer, since this is a homework problem, but here are some hints.
The other answer suggested getLine followed by splitting at words. It sounds like you instead want something more like a conventional tokenizer, which would let you write things like:
(Y
(No (V q))
(V p))
Here’s one implementation that turns a string into tokens that are either a string of alphanumeric characters or a single, non-alphanumeric printable character. You would need to extend it to support quoted strings:
import Data.Char
type Token = String
tokenize :: String -> [Token]
{- Here, a token is either a string of alphanumeric characters, or else one
- non-spacing printable character, such as "(" or ")".
-}
tokenize [] = []
tokenize (x:xs) | isSpace x = tokenize xs
| not (isPrint x) = error $
"Invalid character " ++ show x ++ " in input."
| not (isAlphaNum x) = [x]:(tokenize xs)
| otherwise = let (token, rest) = span isAlphaNum (x:xs)
in token:(tokenize rest)
It turns the example into ["(","Y","(","No","(","V","q",")",")","(","V","p",")",")"]. Note that you have access to the entire repertoire of Unicode.
The main function that evaluates this interactively might look like:
main = interact ( unlines . map show . map evaluate . parse . tokenize )
Where parse turns a list of tokens into a list of ASTs and evaluate turns an AST into a printable expression.
As for implementing the parser, your language appears to have similar syntax to LISP, which is one of the simplest languages to parse; you don’t even need precedence rules. A recursive-descent parser could do it, and is probably the easiest to implement by hand. You can pattern-match on parse ("(":xs) =, but pattern-matching syntax can also implement lookahead very easily, for example parse ("(":x1:xs) = to look ahead one token.
If you’re calling the parser recursively, you would define a helper function that consumes only a single expression, and that has a type signature like :: [Token] -> (AST, [Token]). This lets you parse the inner expression, check that the next token is ")", and proceed with the parse. However, externally, you’ll want to consume all the tokens and return an AST or a list of them.
The stylish way to write a parser is with monadic parser combinators. (And maybe someone will post an example of one.) The industrial-strength solution would be a library like Parsec, but that’s probably overkill here. Still, parsing is (mostly!) a solved problem, and if you just want to get the assignment done on time, using a library off the shelf is a good idea.
the read part of a REPL interpreter typically looks like this
repl :: ForthState -> IO () -- parser definition
repl state
= do putStr "> " -- puts a > character to indicate it's waiting for input
input <- getLine -- this is what you're looking for, to read a line.
if input == "quit" -- allows user to quit the interpreter
then do putStrLn "Bye!"
return ()
else let (is, cs, d, output) = eval (words input) state -- your grammar definition is somewhere down the chain when eval is called on input
in do mapM_ putStrLn output
repl (is, cs, d, [])
main = do putStrLn "Welcome to your very own interpreter!"
repl initialForthState -- runs the parser, starting with read
your eval method will have various loops, stack manipulations, conditionals, etc to actually figure out what the user inputted. hope this helps you with at least the reading input part.

F# write a string of text letter by letter without using loops

I'm doing functional programming with F# at the moment and I'm quite stuck on this. I want to print out a string of text letter by letter without using a loop as that isn't considered functional. I have a very primitive way here:
printf "W"
Thread.Sleep(200)
printf "e"
Thread.Sleep(200)
printf "l"
Thread.Sleep(200)
printf "c"
Thread.Sleep(200)
printf "o"
Thread.Sleep(200)
printf "m"
Thread.Sleep(200)
printf "e "
but obviously, I cannot do that for a 150 character string. If anyone can provide some help or point me in the right direction, it would be most appreciative. Thanks
As mentioned in the comments, blocking a thread and printing are side-effects and so they are not really functional on their own. The nice thing about F# is that you can do side-effects easily if you need to. Typically, you will have some core functional logic, called from a bit of code that does the interaction with user using side-effects.
As you really just need to iterate over a word, for loop does this perfectly:
let msg = "Welcome"
for c in msg do
printf "%c" c
Thread.Sleep(200)
But since you asked about more functional ways, one thing you could learn using this example is recursion (which is quite important in functional programming in general). You can transform for loop into a recursive function like this:
let rec printChars chars =
match chars with
| [] -> ()
| c::rest ->
printfn "%c" c
Thread.Sleep(200)
printChars rest
let msg = "Welcome"
printChars (List.ofSeq msg)
This is not what I'd normally write - because there is no point making code more complicated - but it is useful learning exercise.

Read values from console in a loop in Haskell

I want to read values(strings) from console in a loop until a certain value is entered.
What is the code for that?
With Haskell there are a multitude ways of writing such a loop, and the one you choose will depend on context -- i.e. what larger program is this loop part of?
To get you started with some simple imperative-style loops, both the Haskell Wikibook and the Haskell Wiki have some good resources:
Haskell Simple Input and Output
IO for Imperative Programmers
Update
From your comment it appears you want to write a "command processor". Have a look at this SO question and answer:
Number guessing game error and keeping count of guesses
Alternatively, if your bool expression type has a Show instance how about using the REPL in ghci?
ghci> :load your_code
ghci> let e = ...initial bool expression...
ghci> e
...e is displayed...
ghci> let f = e || blah
ghci> f
...f is displayed...
ghci> it && whatever -- it refers to the last expression
...some output...
ghci> not it
...
it is a variable maintained by ghci which always refers to the last evaluated expression.

Maximal munch in Text.ParserCombinators.ReadP

The Read instance for Double behaves in a very straightforward way:
reads "34.567e8 foo" :: [(Double, String)] = [(3.4567e9," foo")]
However the Read instance for Scientific does something different:
reads "34.567e8 foo" :: [(Scientific, String)] =
[(34.0,".567e8 foo"),(34.567,"e8 foo"),(3.4567e9," foo")]
Strictly this is correct, in that it is presenting a list of possible parses of the input. In fact it could equally well have included (3.0, "4.567e8 foo") in the list, as well as some others. However the usual behaviour in cases like this (which the Double instance follows) is "maximal munch", meaning that the longest valid prefix is parsed.
I'm updating my Decimal library, which has a similar behaviour, and I'm wondering what the Right Thing is here. Both Scientific and Decimal are using Text.ParserCombinators.ReadP, which was designed to make it easy to write Read instances, and this seems to be a characteristic of ReadP parsers.
So my questions:
1: What is the Right Thing for "reads" to return in these cases? Should I file a bug for Data.Scientific?
2: If it should only return the maximal munch (like the Double instance does) then how do you get ReadP to do that?
I've decided that maximal munch is the Right Thing. Given "1.23" a parser that returns 1 is just wrong. I've been tripped up by this myself because I once tried to write a "maybeRead" looking like this:
maybeRead :: (Read a) => String -> Maybe a
maybeRead str = case reads str of
[v, ""] -> Just v
_ => Nothing
This worked fine for Double but failed for Decimal and Scientific. (Obviously it can be fixed to handle multiple return results, but I didn't expect to need to do this).
The problem turned out to be the implementation of "optional" in Text.ParserCombinators.ReadP. This uses the symmetric choice operator "+++", which returns the parse with and without the optional component. Hence when I wrote something like
expPart <- optional "" $ do {...}
the results included a parse without the expPart.
I wrote a different version of "optional" using the left-biased choice operator:
myOpt d p = p <++ return d
If the parser "p" consumes any text then the default is not used. This does the Right Thing if you want maximal munch.
For #2, you could change the scientific package to use this parser defined in terms of the old one: scientificPmaxmuch = scientificP <* eof :: ReadP Scientific.
I don't think there is much of a convention for #1: it doesn't make a difference for people using read or Text.Read.readMaybe. readS_to_P reads :: ReadP Double is probably faster than readS_to_P reads :: ReadP Scientific, but if efficiency mattered at all you would keep everything as ReadP until the end.

Debugging Haskell read function

I'm new to Haskell and I'm writing a simple AI decision system to play a 20 questions style of game. If the program is unable to guess the correct answer, it will ask for a question to use to distinguish the answer and it will store that question in a tree. It reads the tree in from the file system at the start of the program and writes it back out at the end.
I'm having a lot of problems with the serialization code in Haskell. I'm getting the error "Prelude read: no parse". What's going on? Here's my code:
import Data.Char
import System.IO
-- Defines a type for a binary tree that holds the questions and answers
data Tree a =
Answer String |
Question String (Tree a) (Tree a)
deriving (Read, Show)
-- Starts the game running
main = do
let filePath = "data.txt"
fileContents <- readFile filePath
animals <- return (read fileContents)
putStrLn "Think of an animal. Hit Enter when you are ready. "
_ <- getLine
ask animals
writeFile filePath (show animals)
-- Walks through the animals tree and ask the question at each node
ask :: Tree a -> IO ()
ask (Question q yes no) = do
putStrLn q
answer <- getLine
if answer == "yes" then ask yes
else ask no
ask (Answer a) = do
putStrLn $ "I know! Is your animal a " ++ a ++ "?"
answer <- getLine
if answer == "yes" then computerWins
else playerWins
computerWins = do putStrLn "See? Humans should work, computers should think!"
playerWins = do putStrLn "TODO"
And here's the data file I'm using:
Question "Does it live in the water?"
((Question "Does it hop?") (Answer "frog") (Answer "fish"))
(Answer "cow")
read is not intended to handle things like extra parentheses robustly. Your code works for me with the following data file:
Question "Does it live in the water?"
(Question "Does it hop?" (Answer "frog") (Answer "fish"))
(Answer "cow")

Resources