I'm trying to make a function in standard ml that takes a list of pairs of ints, and I should return a list of int that contains the max element from the pairs. (int * int) list -> int list. Now so far,I've written a code but it doesnt work and I cant seem to figure the problem from the error it gave.
Here's the code:
- fun maxpairs x =
= foldr (fn (a, b) => if a > b then a else b) [] x;
And here's the error I'm getting:
stdIn:15.2-15.50 Error: operator and operand don't agree [overload]
operator domain: 'Z
operand: 'Y list
in expression:
(foldr (fn (<pat>,<pat>) => if <exp> then <exp> else <exp>)) nil
foldr takes a function of type ('a * 'b) -> 'b, a value of type 'b and a list of type ['a]. In your case the list is a list of pairs and the value of type 'b is an empty list. That means in the function fn (a,b) => ... a will be a pair and b will be a list. You then try to compare a and b using >. Since > can't be used with a pair as its left operand and a list as its right operand, that doesn't work. Also you can't have an if-statement where the then-expression and the else-expression have different types.
If I were you I'd use map for this, which seems to fit the problem better than using a fold.
Related
I have to write a function like this minByFunction (\x -> -x) [1,2,3,4,5] that gives me as an answer 5. Another example would be minBy length ["a", "abcd", "xx"] gives me "a".
I though I can solve this with something like this:
minBy :: (a -> Bool) -> [a] -> Int
minBy measure list =
case list of
[] -> 0
(x:xs:rest) -> if measure x > measure xs then minBy measure x:rest else minBy measure xs:rest
You need to use parenthesis for (x:rest), otherwise it is interpreted as (minBy measure x) : rest. Since the two recursive calls have minBy measure in common, we can however make a if … then … else … clause for the list with which we make a recursive call.
Furthermore the measure should not per se return a Bool, you want to map it on any type b that is a member of the Ord typeclass.
You also swapped the recursive calls: in case measure x < measure xs, then you should recurse with x:rest and vice versa.
Finally the function should return an a object, so the base case is a singleton list, not an empty list: for an empty list there is no minimum:
minBy :: Ord b => (a -> b) -> [a] -> a
minBy measure list =
case list of
[x] -> x
(x:x2:xs) -> minBy measure (if measure x > measure x2 then x2:xs else x:xs)
The measure function does not return a Bool. In both of the examples you gave, the measure function returns an Int. Also, the final return value of minBy is not necessarily an Int. It is a value with the same type as the elements of the list. So if you give the minBy function a list of strings, the returned value will be a string. With these two considerations in mind, the type signature of minBy should be:
minBy :: (a -> Int) -> [a] -> a
This is not the most general type, however. The value returned by the measure function doesn't have to be an Int, it can also be a Double or a String or anything comparable. The way to express that a value is comparable is with the Ord constraint.
minBy :: (Ord b) => (a -> b) -> [a] -> a
In the first branch of the case expression, you define the minimum value of an empty list to be 0. This definition will fail to type-check. The minimum value of a list must have the same type as the elements of the list, and the type annotation for minBy states that you can give a list of any type, not just a list of integers.
Defining the minimum value of an empty list to be 0 also conflicts with the definition of "minimum value." The empty list doesn't have a minimum value; it has no values at all! A better base case would be: "if the list has just one element, the minimum value is that element."
case list of
[x] -> x
The second branch of your case expression is almost correct; you just need to replace > with <. The first element should be kept if its measure is smaller than the second element's. You also need to surround x:rest in parentheses, because the : operator has lower precedence than function calls. minBy measure x:rest will be parsed as (minBy measure x) : rest, which is not what you want.
minBy :: (Ord b) => (a -> b) -> [a] -> a
minBy measure list =
case list of
[x] -> x
x:y:rest ->
if measure x < measure y
then minBy measure (x:rest)
else minBy measure (y:rest)
I also replaced the variable you called xs with y, because the name xs in Haskell is normally used for lists.
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
So I'm currently studying for an exam and I've been trying to solve this exercise but I really can't figure out how.
I need to implement a function that takes an 'a list and an 'a -> bool function as parameters and returns the number of 'a elements of the list that returns true when given to the 'a -> bool function taken as parameter.
So far this is the code I tried:
test([],funct) = []
|test(x::xs,funct) = if (funct(x) then 1 + test(xs,funct)
else 0 + (xs,funct);
error: Type of clause does not match the type of previous classes;
any help would be appreciated.
If you solve this with folding,
fun countp p xs = List.foldl (fn (x, c) => if p x then c+1 else c) 0 xs
the function will also be tail-recursive.
Two issues:
In the case of the empty list you return a list, not a number.
In the other case, the else part is missing the recursive call to test.
[...] a pair of functions tofun : int -> ('a -> 'a) and fromfun : ('a -> 'a) ->
int such that (fromfun o tofun) n evaluates to n for every n : int.
Anyone able to explain to me what this is actually asking for? I'm looking for more of an explanation of that than an actual solution to this.
What this is asking for is:
1) A higher-order function tofun which when given an integer returns a polymorphic function, one which has type 'a->'a, meaning that it can be applied to values of any type, returning a value of the same type. An example of such a function is:
- fun id x = x;
val id = fn : 'a -> 'a
for example, id "cat" = "cat" and id () = (). The later value is of type unit, which is a type with only 1 value. Note that there is only 1 total function from unit to unit (namely, id or something equivalent). This underscores the difficulty with coming up with defining tofun: it returns a function of type 'a -> 'a, and other than the identity function it is hard to think of other functions. On the other hand -- such functions can fail to terminate or can raise an error and still have type 'a -> 'a.
2) fromfun is supposed to take a function of type 'a ->'a and return an integer. So e.g. fromfun id might evaluate to 0 (or if you want to get tricky it might never terminate or it might raise an error)
3) These are supposed to be inverses of each other so that, e.g. fromfun (tofun 5) needs to evaluate to 5.
Intuitively, this should be impossible in a sufficiently pure functional language. If it is possible in SML, my guess is that it would be by using some of the impure features of SML (which allow for side effects) to violate referential transparency. Or, the trick might involve raising and handling errors (which is also an impure feature of SML). If you find an answer which works in SML it would be interesting to see if it could be translated to the annoyingly pure functional language Haskell. My guess is that it wouldn't translate.
You can devise the following property:
fun prop_inverse f g n = (f o g) n = n
And with definitions for tofun and fromfun,
fun tofun n = ...
fun fromfun f = ...
You can test that they uphold the property:
val prop_test_1 =
List.all
(fn i => prop_inverse fromfun tofun i handle _ => false)
[0, ~1, 1, valOf Int.maxInt, valOf Int.minInt]
And as John suggests, those functions must be impure. I'd also go with exceptions.
I'm looking through some notes that my professor gave regarding the language SML and one of the functions looks like this:
fun max gt =
let fun lp curr [] = curr
| lp curr (a::l) = if gt(a,curr)
then lp a l
else lp curr l
in
lp
end
Could someone help explain what this is doing? The thing that I am most confused about is the line:
let fun lp curr [] = curr
What exactly does this mean? As far as I can tell there is a function called lp but what does the curr [] mean? Are these arguments? If so, aren't you only allowed one parameter in sml?
It means that lp is a function that takes 2 parameters, the first being curr and the second being, well, a list, which logically, may be either empty ([]) or contain at least one element ((a::l) is a pattern for a list where a is at the head, and the rest of the list is l).
If one were to translate that bit of FP code into a certain well-known imperative language, it would look like:
function lp(curr, lst) {
if (lst.length == 0) {
return curr;
} else {
var a = lst[0]; // first element
var l = lst.slice(1, lst.length); // the rest
if (gt(a, curr)) {
return lp(a, l);
} else {
return lp(curr, l)
}
}
}
Quite a mouthful, but it's a faithful translation.
Functional languages are based on the Lambda Calculus, where functions take exactly one value and return one result. While SML and other FP languages are based on this theory, it's rather inconvenient in practice, so many of these languages allow you to express passing multiple parameters to a function via what is known as Currying.
So yes, in ML functions actually take only one value, but currying lets you emulate multiple arguments.
Let's create a function called add, which adds 2 numbers:
fun add a b = a + b
should do it, but we defined 2 parameters. What's the type of add? If you take a look in the REPL, it is val add = fn : int -> int -> int. Which reads, "add is a function that takes an int and returns another function (which takes an int and returns an int)"
So we could also have defined add this way:
fun add a =
fn b => a + b
And you will see that they are alike. In fact it is safe to say that in a way,
the former is syntactic sugar for the later.
So all functions you define in ML, even those with several arguments, are actually functions with one argument, that return functions that accept the second argument and so on. It's a little hard to get used to at first but it
becomes second nature very soon.
fun add a b = a + b (* add is of type int -> int -> int *)
add 1 2 (* returns 3 as you expect *)
(* calling add with only one parameter *)
val add1 = add 1
What's add1? It is a function that will add 1 to the single argument you pass it!
add1 2 (* returns 3 *)
This is an example of partial application, where you are calling a function piecemeal,
one argument at a time, getting back each time, another function that accepts the rest
of the arguments.
Also, there's another way to give the appearance of multiple arguments: tuples:
(1, 2); (* evaluates to a tuple of (int,int) *)
fun add (a,b) = a + b;
add (1, 2) (* passing a SINGLE argument to a function that
expects only a single argument, a tuple of 2 numbers *)
In your question, lp could have also been implemented as lp (curr, someList):
fun max gt curr lst =
let fun lp (curr, []) = curr
| lp (curr, (a::l)) = if gt(a,curr) then lp (a, l)
else lp (curr, l)
in
lp (curr, lst)
end
Note that in this case, we have to declare max as max gt curr lst!
In the code you posted, lp was clearly implemented with currying. And the type of
max itself was fn: ('a * 'a -> bool) -> 'a -> 'a list -> 'a. Taking that apart:
('a * 'a -> bool) -> (* passed to 'max' as 'gt' *)
'a -> (* passed to 'lp' as 'curr' *)
'a list -> (* passed to 'lp' as 'someList' *)
'a (* what 'lp' returns (same as what 'max' itself returns) *)
Note the type of gt, the first argument to max: fn : (('a * 'a) -> bool) - it is a function of one argument ('a * 'a), a tuple of two 'a's and it returns an 'a. So no currying here.
Which to use is a matter of both taste, convention and practical considerations.
Hope this helps.
Just to clarify a bit on currying, from Faiz's excellent answer.
As previously stated SML only allows functions to take 1 argument. The reason for this is because a function fun foo x = x is actually a derived form of (syntactic sugar) val rec foo = fn x => x. Well actually this is not entirely true, but lets keep it simple for a second
Now take for example this power function. Here we declare the function to "take two arguments"
fun pow n 0 = 1
| pow n k = n * pow n (k-1)
As stated above, fun ... was a derived form and thus the equivalent form of the power function is
val rec pow = fn n => fn k => ...
As you might see here, we have a problem expressing the two different pattern matches of the original function declaration, and thus we can't keep it "simple" anymore and the real equivalent form of a fun declaration is
val rec pow = fn n => fn k =>
case (n, k) of
(n, 0) => 1
| (n, k) => n * pow n (k-1)
For the sake of completeness, cases is actually also a derived form, with anonymous functions as the equivalent form
val rec pow = fn n => fn k =>
(fn (n,0) => 1
| (n,k) => n * pow n (k-1)) (n,k)
Note that (n,k) is applied directly to the inner most anonymous function.