Ocaml expression type confusion - function

I wrote this ocaml function:
(* int Base.List.t -> Base.Int.t x Base.Int.t *)
let min_and_max lst =
let mmax = ref Float.neg_infinity
and mmin = ref Float.infinity in
List.iter ~f:(fun v -> let fv = Float.of_int v in
if fv > !mmax then mmax := fv
else if fv < mmin then mmin := fv)
lst;
(Int.of_float !mmin, Int.of_float !mmax)
It is supposed to return the min and max of a list of integers, but when I compile, I get this error:
File "02-exercises/24-refs/problem.ml", line 25, characters 21-23:
Error: This expression has type Base.Float.t = float
but an expression was expected of type int
The error is pointing to the first if statement in that function. I must be making a very obvious mistake, but I can't see it.
Solution taking into account the answers and comments so far:
let min_and_max lst =
match lst with
| [] -> failwith "Cannot find min and max of empty list"
| v::[] -> (v,v)
| a::b::rest ->
let mmax = ref (max a b)
and mmin = ref (min a b) in
List.iter ~f:(fun v ->
if v > !mmax then mmax := v;
if v < !mmin then mmin := v)
rest;
(!mmin, !mmax)

Base disables polymorphic comparison: you need to use a local open to compare floats with > or < : Float.(fv > !mmax ).
p.s.: The gratuitous conversion to float (and the use of references) is a bit strange and non-optimal.

I don't understand how your compiler throws you that error. Your code contains several errors that it should detect before:
You make a wrong use of the label.
In the else arm, you are comparing against the ref mmin and not against its content —you missed the !—.
You confuse int_of_float function with Int.of_float, that don't exists.
In addition, the logical principle of the function isn't adequate. For example, the first value of the list will always enter in the mmax variable, because it will be greater than the negative infinity. But what if this value were the minimum?
Apart from the above, converting an integer to a float in this case is meaningless and causes precision loss and performance decrease. Nor is necessary to use refs.
This isn't a canonical way to proceed in a OCaml context. In OCaml it's important to try to find the simplest possible solution, because as soon as you start to complicate with the types, you end up being unable to solve the disaster.
I propose you a simpler solution for the problem, with the license to compose a polymorphic function, not only to integers:
let min_and_max lst =
(List.fold_left (fun a b -> if a < b then a else b) (List.hd lst) lst),
(List.fold_left (fun a b -> if a > b then a else b) (List.hd lst) lst);;
It's an elegant option and in addition it's based on terminal recursion. However, on that scheme you could redefine the functions yourself without using the predefined ones to go through the lists. You could also choose the two numbers with a single round, but it would be somewhat more complex to do.

Related

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

PolyML Functions and Types

[...] 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.

Difference between let, fun and function in F#

I'm learning F# and I cannot figure out what the difference between let, fun and function is, and my text book doesn't really explain that either. As an example:
let s sym = function
| V x -> Map.containsKey x sym
| A(f, es) -> Map.containsKey f sym && List.forall (s sym) es;;
Couldn't I have written this without the function keyword? Or could I have written that with fun instead of function? And why do I have to write let when I've seen some examples where you write
fun s x =
...
What's the difference really?
I guess you should really ask MSDN, but in a nutshell:
let binds a value with a symbol. The value can be a plain type like an int or a string, but it can also be a function. In FP functions are values and can be treated in the same way as those types.
fun is a keyword that introduces an anonymous function - think lambda expression if you're familiar with C#.
Those are the two important ones, in the sense that all the others usages you've seen can be thought as syntax sugar for those two. So to define a function, you can say something like this:
let myFunction =
fun firstArg secondArg ->
someOperation firstArg secondArg
And that's very clear way of saying it. You declare that you have a function and then bind it to the myFunction symbol.
But you can save yourself some typing by just conflating anonymous function declaration and binding it to a symbol with let:
let myFunction firstArg secondArg =
someOperation firstArg secondArg
What function does is a bit trickier - you combine an anonymous single-argument function declaration with a match expression, by matching on an implicit argument. So these two are equivalent:
let myFunction firstArg secondArg =
match secondArg with
| "foo" -> firstArg
| x -> x
let myFunction firstArg = function
| "foo" -> firstArg
| x -> x
If you're just starting on F#, I'd steer clear of that one. It has its uses (mainly for providing succinct higher order functions for maps/filters etc.), but results in code less readable at a glance.
These things are sort of shortcuts to each other.
The most fundamental thing is let. This keyword gives names to stuff:
let name = "stuff"
Speaking more technically, the let keyword defines an identifier and binds it to a value:
let identifier = "value"
After this, you can use words name and identifier in your program, and the compiler will know what they mean. Without the let, there wouldn't be a way to name stuff, and you'd have to always write all your stuff inline, instead of referring to chunks of it by name.
Now, values come in different flavors. There are strings "some string", there are integer numbers 42, floating point numbers 5.3, Boolean values true, and so on. One special kind of value is function. Functions are also values, in most respects similar to strings and numbers. But how do you write a function? To write a string, you use double quotes, but what about function?
Well, to write a function, you use the special word fun:
let squareFn = fun x -> x*x
Here, I used the let keyword to define an identifier squareFn, and bind that identifier to a value of the function kind. Now I can use the word squareFn in my program, and the compiler will know that whenever I use it I mean a function fun x -> x*x.
This syntax is technically sufficient, but not always convenient to write. So in order to make it shorter, the let binding takes an extra responsibility upon itself and provides a shorter way to write the above:
let squareFn x = x*x
That should do it for let vs fun.
Now, the function keyword is just a short form for fun + match. Writing function is equivalent to writing fun x -> match x with, period.
For example, the following three definitions are equivalent:
let f = fun x ->
match x with
| 0 -> "Zero"
| _ -> "Not zero"
let f x = // Using the extra convenient form of "let", as discussed above
match x with
| 0 -> "Zero"
| _ -> "Not zero"
let f = function // Using "function" instead of "fun" + "match"
| 0 -> "Zero"
| _ -> "Not zero"

What does this function signature mean in sml?

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.

Haskell IO Passes to Another Function

This question here is related to
Haskell Input Return Tuple
I wonder how we can passes the input from monad IO to another function in order to do some computation.
Actually what i want is something like
-- First Example
test = savefile investinput
-- Second Example
maxinvest :: a
maxinvest = liftM maximuminvest maxinvestinput
maxinvestinput :: IO()
maxinvestinput = do
str <- readFile "C:\\Invest.txt"
let cont = words str
let mytuple = converttuple cont
let myint = getint mytuple
putStrLn ""
-- Convert to Tuple
converttuple :: [String] -> [(String, Integer)]
converttuple [] = []
converttuple (x:y:z) = (x, read y):converttuple z
-- Get Integer
getint :: [(String, Integer)] -> [Integer]
getint [] = []
getint (x:xs) = snd (x) : getint xs
-- Search Maximum Invest
maximuminvest :: (Ord a) => [a] -> a
maximuminvest [] = error "Empty Invest Amount List"
maximuminvest [x] = x
maximuminvest (x:xs)
| x > maxTail = x
| otherwise = maxTail
where maxTail = maximuminvest xs
In the second example, the maxinvestinput is read from file and convert the data to the type maximuminvest expected.
Please help.
Thanks.
First, I think you're having some basic issues with understanding Haskell, so let's go through building this step by step. Hopefully you'll find this helpful. Some of it will just arrive at the code you have, and some of it will not, but it is a slowed-down version of what I'd be thinking about as I wrote this code. After that, I'll try to answer your one particular question.
I'm not quite sure what you want your program to do. I understand that you want a program which reads as input a file containing a list of people and their investments. However, I'm not sure what you want to do with it. You seem to (a) want a sensible data structure ([(String,Integer)]), but then (b) only use the integers, so I'll suppose that you want to do something with the strings too. Let's go through this. First, you want a function that can, given a list of integers, return the maximum. You call this maximuminvest, but this function is more general that just investments, so why not call it maximum? As it turns out, this function already exists. How could you know this? I recommend Hoogle—it's a Haskell search engine which lets you search both function names and types. You want a function from lists of integers to a single integer, so let's search for that. As it turns out, the first result is maximum, which is the more general version of what you want. But for learning purposes, let's suppose you want to write it yourself; in that case, your implementation is just fine.
Alright, now we can compute the maximum. But first, we need to construct our list. We're going to need a function of type [String] -> [(String,Integer)] to convert our formattingless list into a sensible one. Well, to get an integer from a string, we'll need to use read. Long story short, your current implementation of this is also fine, though I would (a) add an error case for the one-item list (or, if I were feeling nice, just have it return an empty list to ignore the final item of odd-length lists), and (b) use a name with a capital letter, so I could tell the words apart (and probably a different name):
tupledInvestors :: [String] -> [(String, Integer)]
tupledInvestors [] = []
tupledInvestors [_] = error "tupledInvestors: Odd-length list"
tupledInvestors (name:amt:rest) = (name, read amt) : tupledInvestors rest
Now that we have these, we can provide ourselves with a convenience function, maxInvestment :: [String] -> Integer. The only thing missing is the ability to go from the tupled list to a list of integers. There are several ways to solve this. One is the one you have, though that would be unusual in Haskell. A second would be to use map :: (a -> b) -> [a] -> [b]. This is a function which applies a function to every element of a list. Thus, your getint is equivalent to the simpler map snd. The nicest way would probably be to use Data.List.maximumBy :: :: (a -> a -> Ordering) -> [a] -> a. This is like maximum, but it allows you to use a comparison function of your own. And using Data.Ord.comparing :: Ord a => (b -> a) -> b -> b -> Ordering, things become nice. This function allows you to compare two arbitrary objects by converting them to something which can be compared. Thus, I would write
maxInvestment :: [String] -> Integer
maxInvestment = maximumBy (comparing snd) . tupledInvestors
Though you could also write maxInvestment = maximum . map snd . tupledInvestors.
Alright, now on to the IO. Your main function, then, wants to read from a specific file, compute the maximum investment, and print that out. One way to represent that is as a series of three distinct steps:
main :: IO ()
main = do dataStr <- readFile "C:\\Invest.txt"
let maxInv = maxInvestment $ words dataStr
print maxInv
(The $ operator, if you haven't seen it, is just function application, but with more convenient precedence; it has type (a -> b) -> a -> b, which should make sense.) But that let maxInv seems pretty pointless, so we can get rid of that:
main :: IO ()
main = do dataStr <- readFile "C:\\Invest.txt"
print . maxInvestment $ words dataStr
The ., if you haven't seen it yet, is function composition; f . g is the same as \x -> f (g x). (It has type (b -> c) -> (a -> b) -> a -> c, which should, with some thought, make sense.) Thus, f . g $ h x is the same as f (g (h x)), only easier to read.
Now, we were able to get rid of the let. What about the <-? For that, we can use the =<< :: Monad m => (a -> m b) -> m a -> m b operator. Note that it's almost like $, but with an m tainting almost everything. This allows us to take a monadic value (here, the readFile "C:\\Invest.txt" :: IO String), pass it to a function which turns a plain value into a monadic value, and get that monadic value. Thus, we have
main :: IO ()
main = print . maxInvestment . words =<< readFile "C:\\Invest.txt"
That should be clear, I hope, especially if you think of =<< as a monadic $.
I'm not sure what's happening with testfile; if you edit your question to reflect that, I'll try to update my answer.
One more thing. You said
I wonder how we can passes the input from monad IO to another function in order to do some computation.
As with everything in Haskell, this is a question of types. So let's puzzle through the types here. You have some function f :: a -> b and some monadic value m :: IO a. You want to use f to get a value of type b. This is impossible, as I explained in my answer to your other question; however, you can get something of type IO b. Thus, you need a function which takes your f and gives you a monadic version. In other words, something with type Monad m => (a -> b) -> (m a -> m b). If we plug that into Hoogle, the first result is Control.Monad.liftM, which has precisely that type signature. Thus, you can treat liftM as a slightly different "monadic $" than =<<: f `liftM` m applies f to the pure result of m (in accordance with whichever monad you're using) and returns the monadic result. The difference is that liftM takes a pure function on the left, and =<< takes a partially-monadic one.
Another way to write the same thing is with do-notation:
do x <- m
return $ f x
This says "get the x out of m, apply f to it, and lift the result back into the monad." This is the same as the statement return . f =<< m, which is precisely liftM again. First f performs a pure computation; its result is passed into return (via .), which lifts the pure value into the monad; and then this partially-monadic function is applied, via =<,, to m.
It's late, so I'm not sure how much sense that made. Let me try to sum it up. In short, there is no general way to leave a monad. When you want to perform computation on monadic values, you lift pure values (including functions) into the monad, and not the other way around; that could violate purity, which would be Very Bad™.
I hope that actually answered your question. Let me know if it didn't, so I can try to make it more helpful!
I'm not sure I understand your question, but I'll answer as best I can. I've simplified things a bit to get at the "meat" of the question, if I understand it correctly.
maxInvestInput :: IO [Integer]
maxInvestInput = liftM convertToIntegers (readFile "foo")
maximumInvest :: Ord a => [a] -> a
maximumInvest = blah blah blah
main = do
values <- maxInvestInput
print $ maximumInvest values
OR
main = liftM maximumInvest maxInvestInput >>= print