Operator as an argument in Haskell - haskell

I'm quite new to Haskell, may be it's a stupid question.
What I want is to give to my function as an argument any operator.
For example:
myFunc :: a -> Int -> Int -> Boolean
myFunc operator a b = a operator b
*Project> myFunc (>) 5 2
True
*Project> myFunc (<=) 5 2
False
Help me in advice how to do that please!

You can do that with haskell function arguments.
In your function above, you want myFunc to take a function that takes two Ints and returns a Bool (not a Boolean, you must have typed that wrong). The declaration for that function would be (Int -> Int -> Bool). Therefore, you can write:
myFunc :: (Int -> Int -> Bool) -> Int -> Int -> Bool
myFunc op a b = a `op` b
This defines a higher-order function that takes a function with two Int parameters that returns a Bool (and two Ints). You can now use it like any other function parameter!
Note that this is exactly the same as doing:
myFunc (#) a b = a # b
Or:
myFunc (%) a b = a % b
Because using infix operaters like * or /, or any operator composed only of special characters, without backticks is just shorthand for using them with (typing `/` every time you want to divide something would get annoying!).

Under the hood, functions "exist" without names. Any function you define (or that is already defined in libraries), such as myFunc just is a function value, and the name just gives us a way to refer to it in other code that wants to use it. This is exactly the same as if you write x = 3: the value 3 "exists" independently of the name x, that name just gives us a way to refer to it.
Why is this relevant to your question about passing operators?
Well, as far as Haskell is concerned, operators like > and <= are also just nameless functions that happen to be bound to the names > and <=. The special treatment of them as operators (that you can write them infix between the arguments you're calling them on) is only about the names, and changes if you refer to them with different names.
There are two types of names in Haskell. Alphanumeric names (consisting only of letters, numbers, and underscores), and symbolic names (consisting only of symbol characters). If you have an expression {1} {2} {3}, then if {2} is a symbolic name (and {1} and {3} aren't symbolic names; otherwise you have a syntax error), then the expression is interpreted as meaning "call {2} on the arguments {1} and {3}". But if none of them are symbolic names, then it's instead interpreted as "call {1} on the arguments {2} and {3}".1
But all of this happens only with reference to the name, not to the functions actually referred to by those names. So if you write your myFunc like so:
myFunc operator a b = operator a b
Then it doesn't actually matter whether myFunc was called like myFunc (+) 1 2 or like myFunc plus 1 2; inside the definition of myFunc the "operator" is referred to by the name operator, which is an alphanumeric name. So you put it first when you want to call it, with its arguments following.
Alternatively you could use a symbolic name inside myFunc, like so:
myFunc ($&^*) a b = a $&^* b
Again, this also works even when myFunc was called with a non-operator function like myFunc plus 1 2.
And of course, there are ways to convert either kind of name to work like the other; you can put an alphanumeric name in backticks to use it infix like an operator:
myFunc operator a b = a `operator` b
And you can put a symbolic name in parentheses to simply use it as reference to the function it's bound to (and this is in fact the only way to use an operator without providing arguments for it):
myFunc ($^&*) a b = ($&^*) a b
So basically, the only special thing you needed to know to pass an operator to your function is what you already knew: put the operator in parentheses when you call the function. Inside the definition of the function, you can write it exactly the same as any other function; the style of name you choose in that function definition will determine whether you call it like an operator or like an ordinary function. You don't need to know (and in fact cannot find out) whether it was an operator "outside" the function.
1 Of course, when you have more complex expressions involving more than 3 things and multiple operators, then the rules of precedence and associativity come into play to determine exactly what's going on.

Related

Does Haskell have implicit pattern matching?

Take this example:
module Main where
main = print (reverseWords "lol")
reverseWords :: String -> [String]
reverseWords = words
reverseWords function is not pattern matching against any argument here yet the function runs and outputs "[lol]".
I have two questions here:
How does Haskell know whether or not I am invoking the words function against the input to reverseWords? In this syntax it looks like I am simply returning the function words.
Why is this able to run successfully even though I have not provided any input arguments in the pattern to reverseWords?
You're just saying that reverseWords is the function words. Anywhere that reverseWords appears, it can be replaced by the function words. So print (reverseWords "lol") is exactly equivalent to print (words "lol"). Basically, you have this new function reverseWords that takes a String argument just like words does and simply passes that argument to words, returning whatever words returns for that argument. Your definition of reverseWords is equivalent to:
reverseWords :: String -> [String]
reverseWords s = words s
Given all of that, reverseWords is a misleading name because it's not doing anything differently than words. So, you're not really doing anything useful at all, just renaming something. A better example would be this:
reverseWords :: String -> [String]
reverseWords = reverse . words
where reverse is some other function you compose with words using the composition operator (.) to make a new function that does something useful. That's called point-free style, where you define new functions by combining other functions without referring to any arguments. That definition is equivalent to:
reverseWords :: String -> [String]
reverseWords s = reverse (words s)
You're declaring a new function reverseWords. First you declare it's type:
reverseWords :: String -> [String]
So it's going to be a function that takes a string and returns a list of strings.
Now there are two ways we can approach this. The first is to write a rule that says that when reverseWords receives some argument, the result is an expression (probably involving calling other functions and using the argument) for a list of strings. Like this:
reverseWords s = words s
This says "expressions of the form reverseWords s are defined to be equal to words s". So then the compiler knows that reverseWords "lol" is equal to words "lol". The function reverseWords is implicitly defined by the rules we write for it1.
But there's another way we can think about this. I assume you're perfectly comfortable with how this works:
myFavouriteNumber :: Integer
myFavouriteNumber = 28
We first declare that myFavouriteNumber will be of type Integer, and then define it by just writing down an integer.
Well, functions are first class values in Haskell, which means we don't only have to define them using dedicated special-purpose syntax. If we can make definitions of type Integer by just writing down an integer, we should be able to make definitions of type String -> [String] by just writing down something with that type, rather than writing down rules. That is what is going on in this form:
reverseWords = words
Rather than writing a rule for what the result of reverseWords will be when it's applied to something, we just write down what reverseWords is. In this case, we tell the compiler that reverseWords is defined to be equal to words. That still lets the compiler know that reverseWords "lol" is equal to words "lol", but it does it just by looking at reverseWords part; it could work that out even without looking at the "lol".
Furthermore, we can also write definitions like this:
two :: Integer
two = 1 + 1
Here instead of defining two as equal to some pre-existing thing, we calculate its value (from other pre-existing things: 1 and +). And because functions are first class, we can do the same thing:
reversedWords :: String -> [String]
reversedWords = reverse . words
Here we don't say reversedWords is equal to an existing function, instead we calculate the function that reverseWords is what you get by calling the composition operator . on the pre-existing functions reverse and words. But we're still calculating the function (of type String -> [String]), not the function's result (of type [String]).
So to answer your questions:
How does haskell know whether or not I am invoking the "words" function against the input to reverseWords? In this syntax it looks like I am simply returning the function "words"
Yes, you are just returning the function words. But you're "returning" it as the function reversedWords itself (before it's applied to anything), not as the result of reversedWords when it's applied. And that's how Haskell knows that the words function is to receive the input to reverseWords; reverseWords is equal to words, so any time you pass some input to reverseWords you're really passing it to words.
Why is this able to run successfully even though I have not provided any input arguments in the pattern to reverseWords?
Because you defined the function reverseWords. You defined it by declaring it equal to some other existing function, so it does whatever that function does. Writing rules for function results (based on arguments) is not the only way to define a function.
The fact that you didn't provide a name for the argument of reverseWords in your definition is exactly how Haskell knows that's what you're doing. If you're defining a function of type A -> B and you give a name to the argument, then the right hand side must be something of type B. If you don't, then the right hand side must be something of type A -> B.2
But for your tile question:
Does haskell have implicit pattern matching?
I'm not sure how to answer that, because none of this discussion has involved pattern matching at all. You can use pattern matching to define functions in Haskell, but that's not what is going on here.
1 Okay, in this case reverseWords is pretty explicitly defined by the rule, but in general functions can be defined using multiple rules using pattern matching and guards, and with auxilliary where definitions; the actual value of the function is sort of an emergent property of all the rules (and knowledge of how they'll be tried in order top-down) and where clauses.
2 This logic works regardless of what A and B are. In particular, B could be something with more arrows in it! That is exactly how functions with multiple arguments work in Haskell. A function like:
foo :: Int -> String -> (Int, String)
could be defined by either:
Writing a rule taking two arguments (an Int and a String), with a right hand side of type (Int, String)
Writing a rule taking one argument (an Int), with a right hand side of type String -> (Int, String)
Writing a direct definition with no arguments, with a right hand side of type Int -> String -> (Int, String)
The pattern is clear; each time you add an argument to your rule, the RHS has a type that strips off one more arrow (starting from the left).
All 3 options produce a function foo with the same type that you can call the same way. The internal definition of the function doesn't matter to the outside world.
reverseWord indeed "returns" words without calling it, and so reverseWords s becomes words s -- since reverseWords had returned words, the call reverseWords s had become the call words s.
It's like having the definition foo() { bar } in more conventional syntax, then foo()(x) === bar(x).

Why is (.) called infix as just . rather than `(.)`

I learned that functions can be invoked in two ways; prefix and infix. For example, say I've created this function:
example :: [Char] -> [Char] -> [Char]
example x y = x ++ " " ++ y
I can call it prefix like so:
example "Hello" "World"
or infix like so:
"Hello" `example` "World"
Both of which will result in the list of chars representing a string "Hello World".
However, I am now learning about function composition, and have come across the function defined like so:
(.) :: (b -> c) -> (a -> b) -> a -> c
So, say I was wanting to compose negate with multiplication by three. I would write the prefix invocation like:
negateComposedWithMultByThree = (.) negate (*3)
And the infix invocation like:
negateComposedWithMultByThree = negate `(.)` (*3)
But, whilst the prefix invocation compiles, the infix invocation does not and instead gives me the error message:
error: parse error on input `('
It seems, in order to call compose infix, I need to omit the brackets and call it like so:
negateComposedWithMultByThree = negate . (*3)
Can anyone shed any light on this? Why does "Hello" `example` "World" whilst negate `(.)` (*3) does not?
In addition, if I try to make my own function with a signature like this:
(,) :: Int -> Int
(,) x = 1
It does not compile, with the error:
"Invalid type signature (,) : ... Should be of form :: "
There's nothing deep here. There's just two kinds of identifiers that have different rules about how they're parsed: by-default-infix, and by-default-prefix. You can tell which is which, because by-default-infix identifiers contain only punctuation, while by-default-prefix identifiers contain only numbers, letters, apostrophes, and underscores.
Recognizing that the default isn't always the right choice, the language provides conversions away from the default behavior. So there are two separate syntax rules, one that converts a by-default-infix identifier to prefix (add parentheses), and one that converts a by-default-prefix identifier to infix (add backticks). You can not nest these conversions: a by-default-infix identifier converted to prefix form is not a by-default-prefix identifier.
That's it. Nothing fundamentally interesting -- all of them become just function applications once parsed -- it's just syntax sugar.

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

function name vs variable in haskell

From haskell documentation:
Identifiers are lexically distinguished into two namespaces (Section 1.4): those that begin with a lower-case letter (variable
identifiers) and those that begin with an upper-case letter
(constructor identifiers).
So a variable containing a constant value, i.e a=4 and the function name add add a b = a + b are both variable identifiers, true? Can we say that a function name is variable?
From another academic source:
f (patter1)...(pattern2) = expression
..where a pattern can be constructor or a variable, not a defined
function
This is where I get confused. As I can do f g x where g is a function, I again see that a function name is a variable then. True?
What do they mean with "not a defined defined function" then?
A function name can be a variable identifier, except when it is an operator like +.
This is a statement about lexical matters.
You can't infer from that that a function name is a variable. (Because a variable is not a lexical thing.)
It is the other way around, like in
f . g = \a -> f (g a)
where f and g are variables, i.e. names that are bound to some unknown-in-advance values, but we know that those values must be functions.
A named function is indeed just a global variable who's "value" just happens to be a function. For example,
id x = x
can just as well be written as
id = ( \ x -> x )
Haskell explicitly makes no distinction between these two. Even the type signature says it:
id :: x -> x
So id is just a value who's value has type x -> x (i.e., a function).
Somebody else said something about operators not being variables; this is untrue.
let (<+>) = \ x y -> (x+y)/(x*y) in 5 <+> 6
You can even do something utterly horrifying like write a loop where the contents of <+> changes each time through the loop. (But why in the hell would anybody ever do that?)

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