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.
Related
I'm beginner in F#, What does %-5s and %5s do in the following code? I thought it gives space paddings but I'm not sure how it pads?
printfn "%-5s %5s" "a" "b"
When I tried printf "%-5s %5s" "a" "b" "v"
or printf "%-5s %-5s" "a" "b" "c"
That gives me an type match error, I don't understand the syntax, It dosen't seem that it is printing the concatenation of the three strings "%-5s %5s", "a" and "b". It seems to put "a" and "b" between the %5s. so why can't I add "c" after? Also, I'm following tutorial on Youtube: https://www.youtube.com/watch?v=c7eNDJN758U
If There is any other good source of learning the essence of functional language by F#, please give some suggesting!
The %5s and %-5s are formatting codes along with width and alignments specified.
The hyphen in your first code aligns the value to the left.
As an example, I have the following 2 lines:
printfn "%-5s %5s" "a" "b"
printfn "%-5s %5s" "yo" "hey!"
What gets printed is the following:
a b
yo hey!
Here is a page that explains more about the printfn function. The entire site is an excellent resource for learning to use F#.
Good luck!
PS - as for your question about the error when adding the 3rd parameter, the printfn function will check for both the types and number of parameters you supply based on the format codes in the string. This is explained in the linked page I included earlier.
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.
I made Read and Show instances of my data, but did not understand the Read instance
data Tests = Zero
| One Int
| Two Int Double
instance Show Tests where
show Zero = "ZERO"
show (One i) = printf "ONE %i" i
show (Two i j) = printf "TWO %i %f" i j
instance Read Tests where
readsPrec _ str = [(mkTests str, "")]
mkTests :: String -> Tests
mkTests = check . words
check :: [String] -> Tests
check ["ZERO"] = Zero
check ["ONE", i] = One (read i)
check ["TWO", i, j] = Two (read i) (read j)
check _ = error "no parse"
main :: IO ()
main = do
print Zero
print $ One 10
print $ Two 1 3.14
let x = read "ZERO" :: Tests
print x
let y = read "ONE 2" :: Tests
print y
let z = read "TWO 2 5.5" :: Tests
print z
This is output
ZERO
ONE 10
TWO 1 3.14
ZERO
ONE 2
TWO 2 5.5
Here are questions:
What is recommend way to implement Read instance?
The minimal complete definition of Read class is readsPrec | readPrec
and readPrec :: ReadPrec a description wrote
Proposed replacement for readsPrec using new-style parsers (GHC only).
Should I use readPrec instead, How? I can't find any example on the net that I can understand.
What is the new-style parsers, is it parsec?
What is the first Int argument of readsPrec :: Int -> ReadS a , is using for?
Is there anyway to somehow deriving Read from Show?
In the past I could use deriving (Show,Read) to most of the job. But this time I want to move to next level.
In my opinion the correct way to implement Read is to derive it and otherwise, it is likely better to move on to more sophisticated parsers. Here is answers to all of your questions anyways.
readPrec is a simple parser combinator based approach for that GHC provides. If you are willing to sacrifice portability for your Read instance you can use it and it makes parsing easier.
I include a small example of how you could use readPrec below
parsec is different from readPrec, however both are parser combinator like. Parsec is a much more complete parser library. Another parser combinator library is attoparsec which works very similarly to parsec.
parsec and attoparsec can't be used with the ordinary Read typeclass (at least directly) but the greater flexibility they offer makes them a good idea for any time you want more complex parsing.
The Int argument to readsPrec is for dealing with precedence when parsing. This might matter when you want to parse arithmetic expressions. You can choose to fail parsing if the precedence is higher than the precedence of the current operator.
Deriving Read from Show isn't possible unfortunately.
Here are a couple of snippets that show how I would implement Read using ReadPrec.
ReadPrec example:
instance Read Tests where
readPrec = choice [pZero, pOne, pTwo] where
pChar c = do
c' <- get
if c == c'
then return c
else pfail
pZero = traverse pChar "ZERO" *> pure Zero
pOne = One <$> (traverse pChar "ONE " *> readPrec)
pTwo = Two <$> (traverse pChar "TWO " *> readPrec) <*> readPrec
In general implementing Read is less intuitive than more heavyweight parsers. Depending on what you want to parse I highly suggest learning parsec or attoparsec since they are extremely useful when you want to parse even more complicated things.
When quoting
<# 1 + 1 #>
I want "1 + 1"
instead of
"Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32),
[Value (1), Value (1)])"
You'll have to write it yourself. See the F# quotations visualizer code as a guide for transforming the quotations abstract syntax tree.
I have implemented a quotation decompiler as part of a larger open source project Unquote. It can decompile many simple F# quoted expressions as single-line non-light syntax strings (see the project's home page for a list of decompiler features). For example,
> decompile <# (11 + 3) / 2 = String.length ("hello world".Substring(4, 5)) #>;;
val it : string =
"(11 + 3) / 2 = String.length ("hello world".Substring(4, 5))"
#Kurt Schelfthout is correct about the many challenges faced when decompiling F# Quotations into human readable form. But from my work so far, I believe that it is possible to write a quotation decompiler which can generate correct F# code. Take match expressions and computation expressions for example, the Unquote decompiler can produce correct F# code in the following simple cases:
> decompile <# match true with | true -> "hi" | _ -> "bye" #>;;
val it : string =
"let matchValue = true in if matchValue then "hi" else "bye""
> decompile <# seq {yield 1; yield 2} #>;;
val it : string =
"seq (Seq.delay (fun unitVar -> Seq.append (Seq.singleton 1) (Seq.delay (fun unitVar -> Seq.singleton 2))))"
Infix and prefix operators are not too hard (as you can see in the first example), but source structure such as new lines and indentation is an interesting topic (though not terribly difficult, I think). However, single-line non-light syntax is sufficient for Unquote's requirements.
There is none, and it's not quite that easy, except in very simple cases. One of the main problems, for example, is the match construct. It is syntactic sugar for a whole bunch of if and switch statements (try printing a quotation with a match in, you'll see). Another one of those biggies are computation expressions, but I guess you could skip those at first.
Then there is a the rabbit hole of ambiguities you'll have to resolve, with conventions like the pipe operator starts a new line, let starts a new line, indentation, infix, prefix, special cases like the (::) operator and so forth.
All in all, doable, but not trivial. Sort of like decompiling.
I wrote the follwing function:
let str2lst str =
let rec f s acc =
match s with
| "" -> acc
| _ -> f (s.Substring 1) (s.[0]::acc)
f str []
How can I know if the F# compiler turned it into a loop? Is there a way to find out without using Reflector (I have no experience with Reflector and I Don't know C#)?
Edit: Also, is it possible to write a tail recursive function without using an inner function, or is it necessary for the loop to reside in?
Also, Is there a function in F# std lib to run a given function a number of times, each time giving it the last output as input? Lets say I have a string, I want to run a function over the string then run it again over the resultant string and so on...
Unfortunately there is no trivial way.
It is not too hard to read the source code and use the types and determine whether something is a tail call by inspection (is it 'the last thing', and not in a 'try' block), but people second-guess themselves and make mistakes. There's no simple automated way (other than e.g. inspecting the generated code).
Of course, you can just try your function on a large piece of test data and see if it blows up or not.
The F# compiler will generate .tail IL instructions for all tail calls (unless the compiler flags to turn them off is used - used for when you want to keep stack frames for debugging), with the exception that directly tail-recursive functions will be optimized into loops. (EDIT: I think nowadays the F# compiler also fails to emit .tail in cases where it can prove there are no recursive loops through this call site; this is an optimization given that the .tail opcode is a little slower on many platforms.)
'tailcall' is a reserved keyword, with the idea that a future version of F# may allow you to write e.g.
tailcall func args
and then get a warning/error if it's not a tail call.
Only functions that are not naturally tail-recursive (and thus need an extra accumulator parameter) will 'force' you into the 'inner function' idiom.
Here's a code sample of what you asked:
let rec nTimes n f x =
if n = 0 then
x
else
nTimes (n-1) f (f x)
let r = nTimes 3 (fun s -> s ^ " is a rose") "A rose"
printfn "%s" r
I like the rule of thumb Paul Graham formulates in On Lisp: if there is work left to do, e.g. manipulating the recursive call output, then the call is not tail recursive.