Understanding the use of brackets in the all function in Haskell? - function

I'm trying to wrap my head around the conventions and rules of programming in Haskell. One thing that I find confusing or difficult to understand is the use of brackets (). Can anyone explain to me what it does in the case of the all function?
all :: (a -> Bool) -> [a] -> Bool
all p xs = and [ p x | x <- xs ]
As I understand it, the type of a function shows the type constraints, inputs and outputs. Wouldn't having
all :: [a] -> Bool
Be enough?

What parentheses do here
Parentheses in Haskell serve a purpose that is very similar to most other programming languages: changing precedence of operations and/or grouping terms.
In your case, the fact that (a -> Bool) is wrapped in parentheses shows that the type of the function's first parameter is a -> Bool. If there was no parentheses (i.e. if the signature was all :: a -> Bool -> [a] -> Bool), then the meaning would be that the type of the function's first parameter is a, and the type of the function's second parameter is Bool.
Wouldn't it be enough to have all :: [a] -> Bool?
If that was the signature, then the question would be: what does such function mean? Does it return True when the list is not empty? Or when it's empty? Or when it contains precisely 42 elements? A bad name for a function. Should have named it has42Elements instead of all.
On the other hand, if the function takes the first parameter of type a -> Bool (that is, a function that takes an a and returns a Bool), then the meaning of all would be "check if this function is True for all elements in this list".

Related

Unable to define a parser in Haskell: Not in scope: type variable ‘a’

I am trying to define a parser in Haskell. I am a total beginner and somehow didn't manage to find any solution to my problem at all.
For the first steps I tried to follow the instructions on the slides of a powerpoint presentation. But I constantly get the error "Not in scope: type variable ‘a’":
type Parser b = a -> [(b,a)]
item :: Parser Char
item = \inp -> case inp of
[] -> []
(x:xs) -> [(x:xs)]
error: Not in scope: type variable ‘a’
|
11 | type Parser b = a -> [(b,a)]
| ^
I don't understand the error but moreover I don't understand the first line of the code as well:
type Parser b = a -> [(b,a)]
What is this supposed to do? On the slide it just tells me that in Haskell, Parsers can be defined as functions. But that doesn't look like a function definition to me. What is "type" doing here? If it s used to specify the type, why not use "::" like in second line above? And "Parser" seems to be a data type (because we can use it in the type definition of "item"). But that doesn't make sense either.
The line derives from:
type Parser = String -> (String, Tree)
The line I used in my code snippet above is supposed to be a generalization of that.
Your help would be much appreciated. And please bear in mind that I hardly know anything about Haskell, when you write an answer :D
There is a significant difference between the type alias type T = SomeType and the type annotation t :: SomeType.
type T = Int simply states that T is just another name for the type Int. From now on, every time we use T, it will be replaced with Int by the compiler.
By contrast, t :: Int indicates that t is some value of type Int. The exact value is to be specified by an equation like t = 42.
These two concepts are very different. On one hand we have equations like T = Int and t = 42, and we can replace either side with the other side, replacing type with types and values with values. On the other hand, the annotation t :: Int states that a value has a given type, not that the value and the type are the same thing (which is nonsensical: 42 and Int have a completely different nature, a value and a type).
type Parser = String -> (String, Tree)
This correctly defines a type alias. We can make it parametric by adding a parameter:
type Parser a = String -> (String, a)
In doing so, we can not use variables in the right hand side that are not parameters, for the same reason we can not allow code like
f x = x + y -- error: y is not in scope
Hence you need to use the above Parser type, or some variation like
type Parser a = String -> [(String, a)]
By contrast, writing
type Parser a = b -> [(b, a)] -- error
would use an undeclared type b, and is an error. At best, we could have
type Parser a b = b -> [(b, a)]
which compiles. I wonder, though, is you really need to make the String type even more general than it is.
So, going back to the previous case, a possible way to make your code run is:
type Parser a = String -> [(a, String)]
item :: Parser Char
item = \inp -> case inp of
[] -> []
(x:xs) -> [(x, xs)]
Note how [(x, xs)] is indeed of type [(Char, String)], as needed.
If you really want to generalize String as well, you need to write:
type Parser a b = b -> [(b, a)]
item :: Parser Char String
item = \inp -> case inp of
[] -> []
(x:xs) -> [(xs, x)]

When can you call functions with labeled arguments without the labels?

It seems that in certain situations you can call functions with labeled arguments without the labels if they're in the right order; e.g.
let f ~x ~y = Format.sprintf "%d %s" x y;;
f 3 "test";;
runs successfully, but
f "test" 3;;
fails with the error message
Line 1, characters 2-8:
Error: This expression has type string but an expression was expected of type
int
For functions with optional arguments, it seems to work if you don't pass in the optional arguments:
let f ?(x = 1) ~y () = Format.sprintf "%d %s" x y;;
f "help" ();;
succeeds, but
f 2 "help" ();;
fails with the error message
Line 1, characters 4-10:
Error: The function applied to this argument has type
?x:int -> y:string -> string
This argument cannot be applied without label
Is there a general rule for when this is possible?
You can omit labels if the application is total (i.e., all required arguments are provided) and if the return type of the function is not a type variable. Arguments to the optional parameters must always be passed by a label.
Let's do some examples,
let example1 ?(opt=0) ~a ~b ~c unlabeled =
opt + a + b + c + unlabeled;;
example1 1 2 3 4;;
- : int = 10
Here we were able to apply all arguments without labels, because we have provided all required arguments (the optional parameter is not required, hence the name), and the resulting type is not polymorphic. However, if we will take the List.fold function from Core or ListLabels, which has type
'a list -> init:'accum -> f:('accum -> 'a -> 'accum) -> 'accum
Then we will get,
List.fold [1;2;3;4] 0 (+);;
- : init:(int -> (int -> int -> int) -> '_weak1) ->
f:((int -> (int -> int -> int) -> '_weak1) ->
int -> int -> (int -> int -> int) -> '_weak1) ->
'_weak1
instead of 10, which one would expect. The reason for that is since the resulting type 'accum is a type variable, so it could also be a function, e.g., int -> int or string -> int -> unit, etc -- all those types match with the 'accum type. That basically means that this function accepts a potentially infinite number of positional arguments. Therefore, all arguments that we provided were interpreted as positional, and as a result, we never were able to fill in the labeled arguments, therefore, our application wasn't made total. This actually makes our original definition of the rule at the beginning of the posting redundant - since an application, which type is denoted with a type variable, could never be total.
Note, that this problem only occurs when the return type is a type variable, not just includes some type variables, for example, we can easily omit labels with the List.map function, e.g, given List.map from Core, which has type
'a list -> f:('a -> 'b) -> 'b list
we can easily apply it
# List.map [1;2;3] ident;;
- : int Core_kernel.List.t = [1; 2; 3]
With all that being said, it is usually assumed a bad practice to omit the labels. Mainly because of the caveats with polymorphic return types and because it makes the order of the labeled arguments important, which is sort of counter-intuitive.
Yes, there is a general rule for this. From the manual:
Formal parameters and arguments are matched according to their respective labels, the absence of label being interpreted as the empty label. This allows commuting arguments in applications. One can also partially apply a function on any argument, creating a new function of the remaining parameters.
If several arguments of a function bear the same label (or no label), they will not commute among themselves, and order matters. But they can still commute with other arguments.
As an exception to the above parameter matching rules, if an application is total (omitting all optional arguments), labels may be omitted. In practice, many applications are total, so that labels can often be omitted.

Haskell Fold implementation of `elemIndex`

I am looking at Haskell elemIndex function:
elemIndex :: Eq a => a -> [a] -> Maybe Int
What does Maybe mean in this definition? Sometimes when I call it, the output has a Just or a Nothing What does it mean? How can I interpret this if I were to use folds?
First question:
What does it mean?
This means that the returned value is either an index (Int) or Nothing.
from the docs:
The elemIndex function returns the index of the first element in the given list which is equal (by ==) to the query element, or Nothing if there is no such element.
The second question:
How can I interpret this if I were to use folds?
I'm not sure there is enough context to the "were to use folds" part. But, there are at least 2 ways to use this function:
case analysis, were you state what to return in each case:
case elemIndex xs of
Just x -> f x -- apply function f to x.
Nothing -> undefined -- do something here, e.g. give a default value.
use function maybe:
maybe defaultValue f (elemIndex xs)
Maybe is a sum type.
Sum type is any type that has multiple possible representations.
For example:
data Bool = False | True
Bool can represented as True or False. The same goes with Maybe.
data Maybe a = Nothing | Just a
The Maybe type encapsulates an optional value. A value of type Maybe a either contains a value of type a (represented as Just a), or it is empty (represented as Nothing)
elemIndex :: Eq a => a -> [a] -> Maybe Int
The elemIndex function returns the index of the first element in the given list which is equal (by ==) to the query element, or Nothing if there is no such element.
Lets compare it to the indexOf function
What are the possible values of this method?
The index of the element in the array in case it was found (lets say 2).
-1 in case it was not found.
Another way to represent it:
Return a number in case it was found - Just 2.
Instead of returning magic numbers like -1 we can return a value that represents the
option of a failure - Nothing.
Regarding "How can I interpret this if I were to use folds", I do not have enough information to understand the question.
Maybe is a type constructor.
Int is a type. Maybe Int is a type.
String is a type. Maybe String is a type.
For any type a, Maybe a is a type. Its values come in two varieties: either Nothing or Just x where x is a value of type a (we write: x :: a):
x :: a
----------------- ------------------
Just x :: Maybe a Nothing :: Maybe a
In the first rule, the a in both the type of the value x :: a and the type of the value Just x :: Maybe a is the same. Thus if we know the type of x we know the type of Just x; and vice versa.
In the second rule, nothing in the value Nothing itself determines the a in its type. The determination will be made according to how that value is used, i.e. from the context of its usage, from its call site.
As to the fold implementation of elemIndex, it could be for example
elemIndex_asFold :: Eq a => a -> [a] -> Maybe Int
elemIndex_asFold x0 = foldr g Nothing
where
g x r | x == x0 = Just x
| else = r

Number of functions in expression - SML

How many functions are present in this expression? :
'a -> 'a -> ('a*'a)
Also, how would you implement a function to return this type? I've created functions that have for example:
'a -> 'b -> ('a * b)
I created this by doing:
fun function x y = (x,y);
But I've tried using two x inputs and I get an error trying to output the first type expression.
Thanks for the help!
To be able to have two inputs of the same alpha type, I have to specify the type of both inputs to alpha.
E.g
fun function (x:'a) (y:'a) = (x, y);
==>
a' -> 'a -> (a' * 'a)
Assuming this is homework, I don't want to say too much. -> in a type expression represents a function. 'a -> 'a -> ('a * 'a) has two arrows, so 2 might be the answer for your first question, though I find that particular question obscure. An argument could be made that each fun defines exactly one function, which might happen to return a function for its output. Also, you ask "how many functions are present in the expression ... " but then give a string which literally has 0 functions in it (type descriptions describe functions but don't contain functions), so maybe the answer is 0.
If you want a natural example of int -> int -> int * int, you could implement the functiondivmod where divmod x y returns a tuple consisting of the quotient and remainder upon dividing x by y. For example, you would want divmod 17 5 to return (3,2). This is a built-in function in Python but not in SML, but is easily defined in SML using the built-in operators div and mod. The resulting function would have a type of the form 'a -> 'a -> 'a*'a -- but for a specific type (namely int). You would have to do something which is a bit less natural (such as what you did in your answer to your question) to come up with a polymorphic example.

Partial application of operators

If I want to add a space at the end of a character to return a list, how would I accomplish this with partial application if I am passing no arguments?
Also would the type be?
space :: Char -> [Char]
I'm having trouble adding a space at the end due to a 'parse error' by using the ++ and the : operators.
What I have so far is:
space :: Char -> [Char]
space = ++ ' '
Any help would be much appreciated! Thanks
Doing what you want is so common in Haskell it's got its own syntax, but being Haskell, it's extraordinarily lightweight. For example, this works:
space :: Char -> [Char]
space = (:" ")
so you weren't far off a correct solution. ([Char] is the same as String. " " is the string containing the character ' '.) Let's look at using a similar function first to get the hang of it. There's a function in a library called equalFilePath :: FilePath -> FilePath -> Bool, which is used to test whether two filenames or folder names represent the same thing. (This solves the problem that on unix, mydir isn't the same as MyDir, but on Windows it is.) Perhaps I want to check a list to see if it's got the file I want:
isMyBestFile :: FilePath -> Bool
isMyBestFile fp = equalFilePath "MyBestFile.txt" fp
but since functions gobble their first argument first, then return a new function to gobble the next, etc, I can write that shorter as
isMyBestFile = equalFilePath "MyBestFile.txt"
This works because equalFilePath "MyBestFile.txt" is itself a function that takes one argument: it's type is FilePath -> Bool. This is partial application, and it's super-useful. Maybe I don't want to bother writing a seperate isMyBestFile function, but want to check whether any of my list has it:
hasMyBestFile :: [FilePath] -> Bool
hasMyBestFile fps = any (equalFilePath "MyBestFile.txt") fps
or just the partially applied version again:
hasMyBestFile = any (equalFilePath "MyBestFile.txt")
Notice how I need to put brackets round equalFilePath "MyBestFile.txt", because if I wrote any equalFilePath "MyBestFile.txt", then filter would try and use just equalFilePath without the "MyBestFile.txt", because functions gobble their first argument first. any :: (a -> Bool) -> [a] -> Bool
Now some functions are infix operators - taking their arguments from before and after, like == or <. In Haskell these are just regular functions, not hard-wired into the compiler (but have precedence and associativity rules specified). What if I was a unix user who never heard of equalFilePath and didn't care about the portability problem it solves, then I would probably want to do
hasMyBestFile = any ("MyBestFile.txt" ==)
and it would work, just the same, because == is a regular function. When you do that with an operator function, it's called an operator section.
It can work at the front or the back:
hasMyBestFile = any (== "MyBestFile.txt")
and you can do it with any operator you like:
hassmalls = any (< 5)
and a handy operator for lists is :. : takes an element on the left and a list on the right, making a new list of the two after each other, so 'Y':"es" gives you "Yes". (Secretly, "Yes" is actually just shorthand for 'Y':'e':'s':[] because : is a constructor/elemental-combiner-of-values, but that's not relevant here.) Using : we can define
space c = c:" "
and we can get rid of the c as usual
space = (:" ")
which hopefully make more sense to you now.
What you want here is an operator section. For that, you'll need to surround the application with parentheses, i.e.
space = (: " ")
which is syntactic sugar for
space = (\x -> x : " ")
(++) won't work here because it expects a string as the first argument, compare:
(:) :: a -> [a] -> [a]
(++) :: [a] -> [a] -> [a]