Haskell record syntax desugared - haskell

I understand how to use record syntax in Haskell, but I have trouble to understand what the thing inside the curly braces is.
data PairRecord = PR {foo::Int, bar::String} deriving (Eq,Show)
x = (PR {foo=1, bar="init"})
y= x {foo=23}
What is this {foo=23} thing? The last line looks as if it was an
argument to the function x, which is clearly not the case.
Is there
anything else I can do with {foo=23} except placing it right behind
a record?
Is there a formal way to desugar it like what we can do with do notation?

This syntax is called "record update" or "update using field labels" and described in Section 3.15.3 of the Haskell 2010 report. It can be desugared. The exact rules are given in the report. In your example, the desugaring of x {foo = 23} is
case x of
PR f b -> PR 23 b
_ -> error "Update error"
Note that the report uses an auxiliary function called "pick" in the desugaring that's described in the section before, 3.15.2, on "Construction using field labels".

by looking at the types:
:t PR
PR :: Int -> String -> PairRecord
so it means you need an Int and a String in order to construct a PairRecord.
Now, in the definition of the PairRecord, you've defined accessor:
:t foo
foo :: PairRecord -> Int
in order to use foo (as accessor), you needs to supply a PairRecord. You gets an
Int as return value:
foo y
23
It means as well foo alone has no meaning, this function needs a PairRecord.
As kosmikus already point out, the syntax
y= x {foo=23}
creates y from an existing PairRecord with an integer set to 23 (with the help of the accessor function).

What you need is called lenses. But firstly you must install package lens.

Related

How to define multiple patterns in Frege?

I'm having some trouble defining a function in Frege that uses multiple patterns. Basically, I'm defining a mapping by iterating through a list of tuples. I've simplified it down to the following:
foo :: a -> [(a, b)] -> b
foo _ [] = [] --nothing found
foo bar (baz, zab):foobar
| bar == baz = zab
| otherwise = foo bar foobar
I get the following error:
E morse.fr:3: redefinition of `foo` introduced line 2
I've seen other examples like this that do use multiple patterns in a function definition, so I don't know what I'm doing wrong. Why am I getting an error here? I'm new to Frege (and new to Haskell), so there may be something simple I'm missing, but I really don't think this should be a problem.
I'm compiling with version 3.24-7.100.
This is a pure syntactical problem that affects newcomers to languages of the Haskell family. It won't take too long until you internalize the rule that function application has higher precedence than infix expression.
This has consequences:
Complex arguments of function application need parentheses.
In infix expressions, function applications on either side of the operator do not need parentheses (however, individual components of function application may still need them).
In Frege, in addition, the following rule holds:
The syntax of function application and infix expressions on the left hand side of a definition is identical to the one on the right hand side as far as lexemes allowed on both sides are concerned. (This holds in Haskell only when # and ~ are not used.)
This is so you can define an addition function like this:
data Number = Z | Succ Number
a + Z = a
a + Succ b = Succ a + b
Hence, when you apply this to your example, you see that syntactically, you're going to redefine the : operator. To achieve what you want, you need to write it thus:
foo bar ((baz, zab):foobar) = ....
-- ^ ^
This corresponds to the situation where you apply foo to a list you are constructing:
foo 42 (x:xs)
When you write
foo 42 x:xs
this means
(foo 42 x):xs

Different numbers of arguments when pattern matching Maybe

I've run into a problem I don't really understand. I thought that I would be able to write code like this in Haskell:
foo :: Maybe Int -> Int
foo Nothing = 0
foo Just x = x
But when I try to compile it, I get the error:
Equations for ‘foo’ have different numbers of arguments
I can fix it by changing my code to the following:
foo :: Maybe Int -> Int
foo Nothing = 0
foo (Just x) = x
Which makes me think that GHC is interpreting Just as an argument to foo. But Haskell forbids using uppercase letters to start variable names, so I wouldn't think there should be any ambiguity here. What's going on?
You're correct, there's not ambiguity about whether or not Just is a constructor – but constructors can have no arguments! Haskell's pattern matching doesn't look up the names involved, it's strictly syntactic, and foo Just x = x is a perfectly well-formed function definition clause. It's ill-typed:
Prelude> let foo Just x = x
<interactive>:2:9:
Constructor ‘Just’ should have 1 argument, but has been given none
In the pattern: Just
In an equation for ‘foo’: foo Just x = x
but with different data types around, it'd be fine:
Prelude> data Justice = Just
Prelude> let foo Just x = x
Prelude> :t foo
foo :: Justice -> t -> t
Prelude> foo Just ()
()
Just could be a nullary constructor (as in the second example), and since function application is left-associative, the compiler parses Just and x as separate arguments and you get the "different numbers of arguments" error. (And as you can see above, if there weren't the Nothing case, you'd actually get the type error for code of that form.)
The idea is that pattern syntax should mirror application syntax. If I was calling foo I couldn't write foo Just x, because that means something else (and if foo had type (Int -> Maybe Int) -> Int -> Int then it would even work). Having patterns have different rules for where parentheses are needed than expressions would be very weird.
Writing compound patterns without parentheses and trusting the compiler to automatically group things also falls apart in more complex situations. What should this mean?
foo Just x : xs = ...

Why can you define function without parameter in haskell

I have function add which I apply partially to create a new function addOne.
add :: Int -> (Int -> Int)
add x y = x + y
addOne can be defined with explicit parameter
addOne :: Int -> Int
addOne y = add 1 y
or without explict parameter
addOne :: Int -> Int
addOne = add 1
I have four questions:
Why can I define the new function without explicit parameter?
Is there any difference between these two definitions?
When do I know when I can define function without a parameter?
Which definition is preferred and when?
Because addOne y = add 1 y means addOne = \y -> add 1 y, and \x -> f x is always just f. This is called eta equivalence. So addOne = add 1.
No
Always. Function parameters are just syntactic sugar for lambdas:
add :: Int -> Int -> Int
add = \x y -> x + y
Whether you can remove the variable binding completely is a different matter.
It's always nice to "eta reduce" (that is, remove the rightmost bound variable in a function binding when it matches a function application in the bound expression) when you can, as it avoids introducing a superfluous name.
One of the basic concepts in functional programming that you'll need to learn to use Haskell is that functions are just a kind of value, definitions just name things. It's not like procedural languages where there's a sharp distinction made between functions and variables and function definitions are completely different from variable definitions.
So a variable definition like
addOne :: Int -> Int
addOne = add 1
is just adding a name for the expression add 1, so you can refer to it as addOne. It's identical to a variable declaration.[1] The fact that the value of that variable is a function is almost incidental, from Haskell's perspective.
Your add definition:
add :: Int -> (Int -> Int)
add x y = x + y
is also a variable definition. It's a bit of syntax sugar Haskell provides for:
add :: Int -> Int -> Int
add = \ x -> \ y -> x + y
on the theory that it's easier to read. But it's still just sugar; you never need it (except see [1] below) like you would in other languages.
[1]: The dreaded monomorphism restriction also comes into play here. The idea is just: in a function definition, the RHS will be executed by the computer many times (as many times as you call the function). You are probably aware of this from other languages. In a monomorphic variable definition, the RHS will be executed at most once, which is also similar to how other languages work. However, a polymorphic variable often ends up acting like a function definition, with the RHS being executed as many times as the value of the variable is accessed. So Haskell dis-allows polymorphic definitions unless you have a polymorphic type signature (so you say "I know what I'm doing, allow this variable to be polymorphic") or you have arguments on the left-hand side (so it "looks like" the RHS should be executed many times).

Haskell: type versus pattern matching

I´m a second-year under-graduate student and have just started learning Haskell. My problem is regarding type-handling versus pattern-matching. I have defined a type Car which contains different parameters and the specification if the car´s gearbox is a stick or automatic, like so:
data Car = Stick [Char] Integer | Automatic [Char] Integer
This solution has worked brilliantly for pattern-matching cars so far, but now I need a function which takes a car as input and returns the Stick/Automatic information, and don´t want to have to change the Stick/Automatic handling to string-handling. I don´t know what return-type to specify for that function. What would that return-type be?
You could introduce a new type for the type of tranmission:
data TransmissionType = Stick | Automatic
and change your definition of car to:
data Car = Car TransmissionType [Char] Integer
You can then add a function to get the type
transmissionType :: Car -> TransmissionType
transmissionType (Car t _ _) = t
Since you only have one constructor you could use records instead:
data Car = Car {
transmissionType :: TransmissionType,
field1 :: [Char],
field2 :: Integer
}
If you don't want to change your definition you could add a function
isManual :: Car -> Bool
isManual (Stick _ _) = True
isManual (Automatic _ _) = False
In Haskell, the return-type you write in the code (in the declaration) is not for the compiler. It is for you. The compiler figures out what type your function is, then checks whether you got it right.
What I suggest you do, is to make the function you need. ( I haven't really figured out what that should be.) After you have done that, open ghci (the compiler, interactive), load your code. then use :t to have the compiler figure out what type it is. Then you can write it in the declaration if you want to. It is not necessary.
$ ghci
prelude> :load yourfile
prelude> :t yourfunction

SML conversions to Haskell

A few basic questions, for converting SML code to Haskell.
1) I am used to having local embedded expressions in SML code, for example test expressions, prints, etc. which functions local tests and output when the code is loaded (evaluated).
In Haskell it seems that the only way to get results (evaluation) is to add code in a module, and then go to main in another module and add something to invoke and print results.
Is this right? in GHCi I can type expressions and see the results, but can this be automated?
Having to go to the top level main for each test evaluation seems inconvenient to me - maybe just need to shift my paradigm for laziness.
2) in SML I can do pattern matching and unification on a returned result, e.g.
val myTag(x) = somefunct(a,b,c);
and get the value of x after a match.
Can I do something similar in Haskell easily, without writing separate extraction functions?
3) How do I do a constructor with a tuple argument, i.e. uncurried.
in SML:
datatype Thing = Info of Int * Int;
but in Haskell, I tried;
data Thing = Info ( Int Int)
which fails. ("Int is applied to too many arguments in the type:A few Int Int")
The curried version works fine,
data Thing = Info Int Int
but I wanted un-curried.
Thanks.
This question is a bit unclear -- you're asking how to evaluate functions in Haskell?
If it is about inserting debug and tracing into pure code, this is typically only needed for debugging. To do this in Haskell, you can use Debug.Trace.trace, in the base package.
If you're concerned about calling functions, Haskell programs evaluate from main downwards, in dependency order. In GHCi you can, however, import modules and call any top-level function you wish.
You can return the original argument to a function, if you wish, by making it part of the function's result, e.g. with a tuple:
f x = (x, y)
where y = g a b c
Or do you mean to return either one value or another? Then using a tagged union (sum-type), such as Either:
f x = if x > 0 then Left x
else Right (g a b c)
How do I do a constructor with a tuple argument, i.e. uncurried in SML
Using the (,) constructor. E.g.
data T = T (Int, Int)
though more Haskell-like would be:
data T = T Int Bool
and those should probably be strict fields in practice:
data T = T !Int !Bool
Debug.Trace allows you to print debug messages inline. However, since these functions use unsafePerformIO, they might behave in unexpected ways compared to a call-by-value language like SML.
I think the # syntax is what you're looking for here:
data MyTag = MyTag Int Bool String
someFunct :: MyTag -> (MyTag, Int, Bool, String)
someFunct x#(MyTag a b c) = (x, a, b, c) -- x is bound to the entire argument
In Haskell, tuple types are separated by commas, e.g., (t1, t2), so what you want is:
data Thing = Info (Int, Int)
Reading the other answers, I think I can provide a few more example and one recommendation.
data ThreeConstructors = MyTag Int | YourTag (String,Double) | HerTag [Bool]
someFunct :: Char -> Char -> Char -> ThreeConstructors
MyTag x = someFunct 'a' 'b' 'c'
This is like the "let MyTag x = someFunct a b c" examples, but it is a the top level of the module.
As you have noticed, Haskell's top level can defined commands but there is no way to automatically run any code merely because your module has been imported by another module. This is entirely different from Scheme or SML. In Scheme the file is interpreted as being executed form-by-form, but Haskell's top level is only declarations. Thus Libraries cannot do normal things like run initialization code when loaded, they have to provide a "pleaseRunMe :: IO ()" kind of command to do any initialization.
As you point out this means running all the tests requires some boilerplate code to list them all. You can look under hackage's Testing group for libraries to help, such as test-framework-th.
For #2, yes, Haskell's pattern matching does the same thing. Both let and where do pattern matching. You can do
let MyTag x = someFunct a b c
in ...
or
...
where MyTag x = someFunct a b c

Resources