Strange expression parsing behavior - f#

In this code:
let f(a,b,c) = a * b + c - (d())
let g(a,b,c) = a * b + c -(d())
f is (int*int*int) -> int, and g is (int*int*(int*int)) -> int.
Removing the brackets around d() in g causes the "Successive arguments should be separated by spaces or tupled" error.
What's going on?

#bytebuster is quite correct in his comment, but to put it into layman's terms ;-] one is parsed as the binary subtraction operator and the other is parsed as the unary negation operator – you're simply fighting operator precedence here.

Related

F# three parameter infix operator

How to use a three parametered infix operator?
Eg.: base function is
let orElse labelFunc p1 p2 = {...} and operator let ( <|> ) = orElse
Now, for non-infix version this works nicely:List.reduce ((<|>) labelFunc) parserList.
Can I use it somehow still "infixing"? eg.: (p1 (<|> labelFunc) p1) does not work nor any other combination, other than using the non-infix version here as well.
First of all, I think it's best to restrict the number of custom operators you're using in your code, because custom operators make F# code hard to read. F# lets you define custom operators, but it's not particularly designed to make this a great experience - it makes sense for some small domain-specific languages (like parser combinators), but not much else.
So, while I do not recommend using this, there is a weird trick that you can use to write something like p1 (<op> l) p2, which is to make <op> infix and replace the parentheses with two more custom operators:
let (</) a b = a, b
let (/>) c d = c, d
let (!) f = f
1 </ !10 /> 2
This sample just produces a tuple with all three arguments, but if you implement your logic in the </ operator, it will actually do something like what you want. But as I said, I would not do this :-).
I don't believe there is any good way to achieve that. Once you have a parenthesized expression it won't be parsed as an operator - even 1 (+) 1 doesn't work.

How to use F# exponentiation operator (**) in prefix notation?

With most operators in F# I can use prefix or infix notation, for example:
let x = a + b
is equivalent to
let x = (+) a b
This does not work for the exponentation operator ** however, because the parenthesised version is treated as a comment. That is, (*this is a comment*) is F# syntax for a comment, so (**) is treated as an empty comment.
let x = a ** b // a raised to b
let x = (**) a b // empty comment, followed by function a applied to b
Is there an escape character I can use or is this simply a strange quirk of the language?
Try using spaces between the parentheses, as pointed by kvb in the comments:
let x = ( ** ) a b

Parse Error: (incorrect indentation or misplaced bracket)

I'm starting out to learn Haskell. Even though I'm a dunce extraordinaire, I am intent on making this work. The error I received is listed as the title. This is the code that I wrote to try to implement the behavior of replicating a list (n) times and concatenating its new length as a new list. Now I have a basic understanding of how parsing works in Haskell, below my original code I will give example of some modified code to see if my understanding on parsing is adequate. My question for now is how I can properly indent or structure my block in order to not receive this error (is that specific enough :O) -- is there a piece of information I'm missing when it comes to creating instances and formatting? PLEASE DO NOT TELL ME OR OFFER SUGGESTIONS IF YOU NOTICE THAT MY CURRENT INSTANCE OR MAIN FUNCTION ARE SYNTACTICALLY WRONG. I want to figure it out and will deal with that GHC error when I get to it. (I hope that's the proper way to learn). BUT if I could ask for anyone's help in getting past this first obstacle in understanding proper formatting, I'd be grateful.
module Main where
import Data.List
n :: Int
x :: [Char]
instance Data stutter n x where
x = []
n = replicate >>= x : (n:xs)
stutter >>= main = concat [x:xs]
let stutter 6 "Iwannabehere" -- <-- parse error occurs here!!!
--Modified code with appropriate brackets, at least where I think they go.
module Main where
import Data.List
n :: Int
x :: [Char]
instance Data stutter n x where{
;x = []
;n = replicate >>= x : (n:xs)
;stutter >>= main = concat [x:xs]
;
};let stutter 6 "Iwannabehere" -- there should be no bracket of any kind at the end of this
I placed the 'let' expression on the outside of the block, I don't believe it goes inside and I also receive a parsing error if I do that. Not correct but I thought I'd ask anyway.
I'm not sure what the instance Data stutter n x is supposed to be, the instance XYZ where syntax is used solely for typeclasses, but you have a couple syntax errors here.
First of all, while GHC says that the error is on let stutter 6 "Iwannabehere", your first error occurs before that with stutter >>= main = concat [x:xs]. A single = sign is reserved for assignments, which are merely definitions. You can have assignments at the top level, inside a where block, or inside a let block (the where includes typeclass instance definitions). You can't have an assignment be part of an expression like x >>= y = z.
Your next syntax error is the let itself. let blocks can not appear at the top level, they only appear within another definition. You use let in GHCi but the reasons for that are outside the scope of this answer. Suffice to say that entering expression in GHCi is not equivalent to the top level of a source file.
Next, if you were to use a let block somewhere, it can only contain definitions. The syntax looks more like
let <name> [<args>] = <definition>
[<name> [<args>] = <definition>]
in <expression>
And this whole block makes an expression. For example, you could write
def f(x, y, z):
w = x + y + z
u = x - y - z
return w * u
in Python, and this would be equivalent to the Haskell function definition
f x y z = let w = x + y + z
u = x - y - z
in w * u
It only defines local variables. There is another form when you're using it inside do blocks where you can exclude the in <expression> part, such as
main = do
name <- getLine
let message = if length name > 5 then "short name" else "long name"
goodbye n = putStrLn ("Goodbye, " ++ n)
putStrLn message
goodbye name
Note that there is no need to use in here. You can if you want, it just means you have to start a new do block:
main = do
name <- getLine
let message = ...
goodbye n = ...
in do
putStrLn message
goodbye name
And this isn't as pretty.
Hopefully this points you more towards correct syntax, but it looks like you have some misunderstandings about how Haskell works. Have you looked at Learn You a Haskell? It's a pretty gentle and fun introduction to the language that can really help you learn the syntax and core ideas.
Your parse error is from the let keyword. Remove it and no error related to that will occur. let x = y is only relevant in GHCi and do-blocks, neither of which is relevant at this point. Essentially, just replace it with this line:
theWordIGet = stutter 6 "Iwannabehere"
Secondly, instance keyword in Haskell has absolutley nothing to do with what you want to do at this stage. This is not how Haskell functions are defined, which is what I'm guessing you want to do. This is what you're wanting to do to create a stutter function, assuming it simply repeats a string n times.
stutter :: Int -> String -> String
stutter n x = concat (replicate n x)
You'll also want to remove the type declarations for the (out-of-scope) values n and x: they're not objects, they're arguments for a function, which has its own signature determining the types of n and x within a function call.
Lastly, I imagine you will want to print the value of stutter 6 "Iwannabehere" when the program is executed. To do that, just add this:
main :: IO ()
main = print (stutter 6 "Iwannabehere")
In conclusion, I implore you to start from scratch and read 'Learn You a Haskell' online here, because you're going off in entirely the wrong direction - the program you've quoted is a jumble of expressions that could have a meaning, but are in the wrong place entirely. The book will show you the syntax of Haskell much better that I can write about in this one answer, and will explain fully how to make your program behave in the way you expect.

How to write an infix function

Is there a way to write an infix function not using symbols? Something like this:
let mod x y = x % y
x mod y
Maybe a keyword before "mod" or something.
The existing answer is correct - you cannot define an infix function in F# (just a custom infix operator). Aside from the trick with pipe operators, you can also use extension members:
// Define an extension member 'modulo' that
// can be called on any Int32 value
type System.Int32 with
member x.modulo n = x % n
// To use it, you can write something like this:
10 .modulo 3
Note that the space before . is needed, because otherwise the compiler tries to interpret 10.m as a numeric literal (like 10.0f).
I find this a bit more elegant than using pipeline trick, because F# supports both functional style and object-oriented style and extension methods are - in some sense - close equivalent to implicit operators from functional style. The pipeline trick looks like a slight misuse of the operators (and it may look confusing at first - perhaps more confusing than a method invocation).
That said, I have seen people using other operators instead of pipeline - perhaps the most interesting version is this one (which also uses the fact that you can omit spaces around operators):
// Define custom operators to make the syntax prettier
let (</) a b = a |> b
let (/>) a b = a <| b
let modulo a b = a % b
// Then you can turn any function into infix using:
10 </modulo/> 3
But even this is not really an established idiom in the F# world, so I would probably still prefer extension members.
Not that I know of, but you can use the left and right pipe operators. For example
let modulo x y = x % y
let FourMod3 = 4 |> modulo <| 3
To add a little bit to the answers above, you can create a custom infix operators but the vocabulary is limited to:
!, $, %, &, *, +, -, ., /, <, =, >, ?, #, ^, |, and ~
Meaning you can build your infix operator using combining these symbols.
Please check the full documentation on MS Docs.
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/operator-overloading

Using Parsec to write a Read instance

Using Parsec, I'm able to write a function of type String -> Maybe MyType with relative ease. I would now like to create a Read instance for my type based on that; however, I don't understand how readsPrec works or what it is supposed to do.
My best guess right now is that readsPrec is used to build a recursive parser from scratch to traverse a string, building up the desired datatype in Haskell. However, I already have a very robust parser who does that very thing for me. So how do I tell readsPrec to use my parser? What is the "operator precedence" parameter it takes, and what is it good for in my context?
If it helps, I've created a minimal example on Github. It contains a type, a parser, and a blank Read instance, and reflects quite well where I'm stuck.
(Background: The real parser is for Scheme.)
However, I already have a very robust parser who does that very thing for me.
It's actually not that robust, your parser has problems with superfluous parentheses, it won't parse
((1) (2))
for example, and it will throw an exception on some malformed inputs, because
singleP = Single . read <$> many digit
may use read "" :: Int.
That out of the way, the precedence argument is used to determine whether parentheses are necessary in some place, e.g. if you have
infixr 6 :+:
data a :+: b = a :+: b
data C = C Int
data D = D C
you don't need parentheses around a C 12 as an argument of (:+:), since the precedence of application is higher than that of (:+:), but you'd need parentheses around C 12 as an argument of D.
So you'd usually have something like
readsPrec p = needsParens (p >= precedenceLevel) someParser
where someParser parses a value from the input without enclosing parentheses, and needsParens True thing parses a thing between parentheses, while needsParens False thing parses a thing optionally enclosed in parentheses [you should always accept more parentheses than necessary, ((((((1)))))) should parse fine as an Int].
Since the readsPrec p parsers are used to parse parts of the input as parts of the value when reading lists, tuples etc., they must return not only the parsed value, but also the remaining part of the input.
With that, a simple way to transform a parsec parser to a readsPrec parser would be
withRemaining :: Parser a -> Parser (a, String)
withRemaining p = (,) <$> p <*> getInput
parsecToReadsPrec :: Parser a -> Int -> ReadS a
parsecToReadsPrec parsecParser prec input
= case parse (withremaining $ needsParens (prec >= threshold) parsecParser) "" input of
Left _ -> []
Right result -> [result]
If you're using GHC, it may however be preferable to use a ReadPrec / ReadP parser (built using Text.ParserCombinators.ReadP[rec]) instead of a parsec parser and define readPrec instead of readsPrec.

Resources