How can I implement this function in haskell? - function

I need to implement the find function, which retrieves the value associated with a particular key from a list of key-value pairs belongs to. The key value pairs are defined by simple tuples.
Example:
find 2 [(3,"xy"),(2,"abc"),(4,"qwe")] == "abc"
find 42 [(1,2),(3,4),(42,42)] == 42
My code:
find :: Eq a => a -> [(a, b)] -> b
find 'x (a, b)
| x == a = b

find :: Eq a => a -> [(a, b)] -> Maybe b
find _ [] = Nothing
find x ((a, b):xs)
| x == a = Just b
| otherwise = find x xs
I took the liberty to change the return type of the function signature to Maybe b to cover the case when the searched value is not found. That's customary in these situations in Haskell, as far as I know.
There are 2 basic patterns. If the list is exhausted and no result was found previously, return Nothing. Otherwise, check if it's a match, if so return the value wrapped in Just, otherwise recurse further searching.

Related

trouble understanding calling an F# function

I'am quite new to F#, and was solving some basic exercises when i stumbled upon this function
Give the (most general) types of g1 and g2 and describe what each of these two functions
computes. Your description for each function should focus on what it computes, rather
than on individual computation steps
let rec g1 p = function
| x::xs when p x -> x :: g1 p xs
| _ -> [];;
i don't the understand " when p x " part, or how to call the function. can someone please explain what this function takes in as an argument? as just calling the function like that " g1 [1;2;3] " gives me an error.
Tried calling the function, and tried reading some text books to figure it out
The function keyword is a bit tricky, but it's just syntactical sugar for a match expression. The following two functions are equivalent:
let fooMatch x =
match x with
| 1 -> "one"
| _ -> "not one"
let fooFunction =
function
| 1 -> "one"
| _ -> "not one"
If you use function instead of match, then the (last) argument to the function becomes implicit, rather than explicit, but it's still there. Both versions of foo take one argument.
The when p x -> part is called a guard. In your case, p stands for "predicate" (a function that returns true/false). To call your function, you need pass both a predicate and a list. E.g. g1 (fun x -> x % 2 = 0) [1;2;3].
so this is clearly homework, so I don't want to answer it in full just give guidance.
let rec g1 p = function
| x::xs when p x -> x :: g1 p xs
| _ -> [];;
is tricky because "function" is sort of shorthand sort of hides a parameter, the above is the same as (well almost, but for your purposes it is).
let rec g1 p ys =
match ys with
| x::xs when p x -> x :: g1 p xs
| _ -> [];;
so you can immediately see g1 is a function that takes 2 parameters and returns something
g1 : ? -> ? -> ?
you just need to try and work out if there is anything more you can infer anythng about the ?s.
So F# will look at your implementation and try and infer what it can.
as said by brian, "when p x" is a guard, so p is a function that takes an x and returns a bool
p : ? -> bool
and p is the first param of g1 so
g1 : (? -> bool) -> ? -> ?
etc.
(just be aware you/the F# compiler may not be able to identify a concrete type, like 'bool', sometimes it will infer that it doesnt know the specific type i.e. the function is has a 'parametric' type (generic), so you can get types like
identityFunction : 'a -> 'a
i.e. whatever the type of the thing being passed in, something of the same type will be returned
2nd note is, this function is recursive, so you have to make sure that the types in the recursive call inside the function line up with the types of the function you infer by inspecting the code)

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

Ocaml expression type confusion

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.

max pairs function standard ml

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.

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