ML local enviornment - ml

ML function that will accept a boolean function and a list of values and return the last value in the list that meets the given condition or NONE if no values in the list do
my current function looks like this:
fun last func nil = NONE
| last func L =
let val f =
fun getlast(x) = SOME x
| getlast(x::xs) = getlast xs
in List.filter func L
end;
Can anyone help me debug my code and also help me understand local environment in ML?

You're overcomplicating this a bit, and it's unclear what the purposes of f and getlast could be as you're never using them (and the "definition" of f is a syntax error).
If you test your getlast outside of this function (this is usually a good idea) you'll notice that getlast [] is SOME [] and getlast [1,2,3] is SOME [1,2,3]; getlast y is SOME y no matter what y you pass to it.
Also, the result of List.filter func L is an 'a list, not an 'a option, so it's not very useful as the definition of last.
One way of finding such an element in the list xs is using explicit recursion:
If xs is empty, the result is NONE.
If xs is not empty, first see if there is a "last element" in the tail of xs.
If there is, that's the answer.
If there isn't, then
If func holds for the head of xs, that's your answer.
Otherwise, the result is NONE.
Translating this to ML, it might look something like this:
fun last _ [] = NONE
| last f (x::xs) = case last f xs of
NONE => if f x then SOME x else NONE
| result => result
If you want to use List.filter and avoid manual recursion, then note that the last element of a list is the first element of the reverse of that list:
fun last f xs = case List.rev (List.filter f xs) of
[] => NONE
| y::ys => SOME y

Create your own environment for ML or any new project
$ virtualenv -p python3 env (if you have 2.7,3.5)
$ virtualenv env(only you have 3.5+)
$ source env/bin/activate
$ pip install <packagename>

Related

F# Sort an Array with foldBack or fold.

I am trying to sort an Array by using fold or foldBack.
I have tried achieving this like this:
let arraySort anArray =
Array.fold (fun acc elem -> if acc >= elem then acc.append elem else elem.append acc) [||] anArray
this ofcourse errors horribly. If this was a list then i would know how to achieve this through a recursive function but it is not.
So if anyone could enlighten me on how a workable function given to the fold or foldback could look like then i would be createful.
Before you start advising using Array.sort anArray then this wont do since this is a School assignment and therefore not allowed.
To answer the question
We can use Array.fold for a simple insertion sort-like algorithm:
let sort array =
let insert array x =
let lesser, greater = Array.partition (fun y -> y < x) array
[| yield! lesser; yield x; yield! greater |]
Array.fold insert [||] array
I think this was closest to what you were attempting.
A little exposition
Your comment that you have to return a sorted version of the same array are a little confusing here - F# is immutable by default, so Array.fold used in this manner will actually create a new array, leaving the original untouched. This is much the same as if you'd converted it to a list, sorted it, then converted back. In F# the array type is immutable, but the elements of an array are all mutable. That means you can do a true in-place sort (for example by the library function Array.sortInPlace), but we don't often do that in F#, in favour of the default Array.sort, which returns a new array.
You have a couple of problems with your attempt, which is why you're getting a few errors.
First, the operation to append an array is very different to what you attempted. We could use the yield syntax to append to an array by [| yield! array ; yield element |], where we use yield! if it is an array (or in fact, any IEnumerable), and yield if it is a single element.
Second, you can't compare an array type to an element of the array. That's a type error, because compare needs two arguments of the same type, and you're trying to give it a 'T and a 'T array. They can't be the same type, or it'd be infinite ('T = 'T array so 'T array = 'T array array and so on). You need to work out what you should be comparing instead.
Third, even if you could compare the array to an element, you have a logic problem. Your element either goes right at the end, or right at the beginning. What if it is greater than the first element, but less than the last element?
As a final point, you can still use recursion and pattern matching on arrays, it's just not quite as neat as it is on lists because you can't do the classic | head :: tail -> trick. Here's a basic (not-so-)quicksort implementation in that vein.
let rec qsort = function
| [||] -> [||]
| arr ->
let pivot = Array.head arr
let less, more = Array.partition (fun x -> x < pivot) (Array.tail arr)
[| yield! qsort less ; yield pivot ; yield! qsort more |]
The speed here is probably several orders of magnitude slower than Array.sort because we have to create many many arrays while doing it in this manner, which .NET's Array.Sort() method does not.

Taking two elements from an array and adding them, then adding them back into the array

Im trying to create a calculator in f# using two arrays, one which stores the numbers and the other to store the operator symbols. I need the symbols array to pattern match the symbol and depending on the operator take the first two elements from the array and do the operation and add the new number into the head of the 2nd array.
open System
[<EntryPoint>]
let main argv =
printfn "%A" argv
let Add x y = x + y
let Sub x y = x - y
let Div x y = x * y
let Mul x y = x / y
printfn "1 > Calculator \n2 > Load from txt file"
let chosenIn = Console.ReadLine();
//This is where I need to do the operation and after call the sum function
//again until there's only one element left in the number array
let rec sum num (numArray : int[]) sym (symArray : string[]) () =
let rec calc () =
printfn "Enter Sum"
let input = Console.ReadLine()
let intInput = input.Split()
let numArray = [|for num in intInput do
let v , vp = System.Int32.TryParse(num)
if v then yield vp|]
let symbolArray = [|for symbol in intInput do
match symbol with
| "+" -> yield symbol
| "-" -> yield symbol
| "/" -> yield symbol
| "*" -> yield symbol
| _ -> ignore 0|]
calc()
match chosenIn with
| "1" -> calc()
| "2" -> printfn "File"
| _ -> printfn "Invalid"
0 // return an integer exit code
In response to the answer #Liam Donnelly posted to his own question: I'll leave aside questions like "is that really the best way of solving the problem", just commenting on how to better write the code you currently have.
Array slicing and concatenating the way you are doing it here can be written as
let newNumArray = Array.append [| result |] numArray.[2..]
However, I would use F# lists rather than arrays for your task. With lists, you can do pattern matching to access the first 2 elements. Pattern matching, in my view, wins over direct indexing because you can directly encode corner cases, and get the F# compiler to remind you of corner cases. Do the same thing for the operators. You can do both operators and operands in the same go. It will then look something like this:
let rec sum2 (numArray : int list) (symArray : string list) =
let newNum, newSym =
match numArray with
| [] -> failwith "No numbers left to process"
| arg1 :: [] -> failwith "There's only one number left to process"
| arg1 :: arg2 :: args ->
match symArray with
| op1 :: ops ->
let result =
match op1 with
| "+" -> Add arg1 arg2
| "-" -> Sub arg1 arg2
| "*" -> Mul arg1 arg2
| _ -> failwithf "Operator not recognized: '%s'" op1
// Return the result, concatenate the non-processed
// numbers. Return the non-processed operators
result :: args, ops
| _ -> failwith "I've run out of operators?"
<snip>
Also, returning a "default result" if you don't recognize the operators is something that I consider very risky (even though the practice is rather widespread)
If you use lists (F# lists, that is), you can directly access the elements at indices 1.. via head: let newSymArray = symArray.Head or use List.head
Take a step back each time you see yourself writing a for loop in F#. They are cumbersome to write and error-prone. Most of the typical use-cases for loops are covered by F# library functions, so have a good read through those. Your printing loop can be written way shorter by doing:
newNumArray
|> Seq.iter (printfn "%i")
I've managed to make the function which performs the task I needed for it to do and I'm sure there's a much more code efficient way of taking the first elements of the arrays by using Array.copy with filters but I'm new to f# so I just it the way I was confident with
let rec sum (numArray : int[]) (symArray : string[]) =
let result = match symArray.[0] with
| "+" -> Add numArray.[0] numArray.[1]
| "-" -> Sub numArray.[0] numArray.[1]
| "*" -> Mul numArray.[0] numArray.[1]
| _ -> 0
let newNumArray = [|
for i = 0 to numArray.Length - 1 do
if i = 0 then yield result
if i > 1 then yield numArray.[i]|]
let newSymArray = [|
for i = 0 to symArray.Length - 1 do
if i > 0 then yield symArray.[i]|]
if newNumArray.Length > 1 then
sum newNumArray newSymArray
else
for i = 0 to newNumArray.Length - 1 do
printfn "%i" (newNumArray.[i])

2d Array Sort in Haskell

I'm trying to teach myself Haskell (coming from OOP languages). Having a hard time grasping the immutable variables stuff. I'm trying to sort a 2d array in row major.
In java, for example (pseudo):
int array[3][3] = **initialize array here
for(i = 0; i<3; i++)
for(j = 0; j<3; j++)
if(array[i][j] < current_low)
current_low = array[i][j]
How can I implement this same sort of thing in Haskell? If I create a temp array to add the low values to after each iteration, I won't be able to add to it because it is immutable, correct? Also, Haskell doesn't have loops, right?
Here's some useful stuff I know in Haskell:
main = do
let a = [[10,4],[6,10],[5,2]] --assign random numbers
print (a !! 0 !! 1) --will print a[0][1] in java notation
--How can we loop through the values?
First, your Java code does not sort anything. It just finds the smallest element. And, well, there's a kind of obvious Haskell solution... guess what, the function is called minimum! Let's see what it does:
GHCi> :t minimum
minimum :: Ord a => [a] -> a
ok, so it takes a list of values that can be compared (hence Ord) and outputs a single value, namely the smallest. How do we apply this to a "2D list" (nested list)? Well, basically we need the minimum amongst all minima of the sub-lists. So we first replace the list of list with the list of minima
allMinima = map minimum a
...and then use minimum allMinima.
Written compactly:
main :: IO ()
main = do
let a = [[10,4],[6,10],[5,2]] -- don't forget the indentation
print (minimum $ map minimum a)
That's all!
Indeed "looping through values" is a very un-functional concept. We generally don't want to talk about single steps that need to be taken, rather think about properties of the result we want, and let the compiler figure out how to do it. So if we weren't allowed to use the pre-defined minimum, here's how to think about it:
If we have a list and look at a single value... under what circumstances is it the correct result? Well, if it's smaller than all other values. And what is the smallest of the other values? Exactly, the minimum amongst them.
minimum' :: Ord a => [a] -> a
minimum' (x:xs)
| x < minimum' xs = x
If it's not smaller, then we just use the minimum of the other values
minimum' (x:xs)
| x < minxs = x
| otherwise = minxs
where minxs = minimum' xs
One more thing: if we recurse through the list this way, there will at some point be no first element left to compare with something. To prevent that, we first need the special case of a single-element list:
minimum' :: Ord a => [a] -> a
minimum' [x] = x -- obviously smallest, since there's no other element.
minimum' (x:xs)
| x < minxs = x
| otherwise = minxs
where minxs = minimum' xs
Alright, well, I'll take a stab. Zach, this answer is intended to get you thinking in recursions and folds. Recursions, folds, and maps are the fundamental ways that loops are replaced in functional style. Just try to believe that in reality, the question of nested looping rarely arises naturally in functional programming. When you actually need to do it, you'll often enter a special section of code, called a monad, in which you can do destructive writes in an imperative style. Here's an example. But, since you asked for help with breaking out of loop thinking, I'm going to focus on that part of the answer instead. #leftaroundabout's answer is also very good and you fill in his definition of minimum here.
flatten :: [[a]] -> [a]
flatten [] = []
flatten xs = foldr (++) [] xs
squarize :: Int -> [a] -> [[a]]
squarize _ [] = []
squarize len xs = (take len xs) : (squarize len $ drop len xs)
crappySort :: Ord a => [a] -> [a]
crappySort [] = []
crappySort xs =
let smallest = minimum xs
rest = filter (smallest /=) xs
count = (length xs) - (length rest)
in
replicate count smallest ++ crappySort rest
sortByThrees xs = squarize 3 $ crappySort $ flatten xs

Haskell - check whether a 2D list has the same number of rows as columns

I have a 2D list [[Int]] in Haskell and I want to check two things:
whether the list has the sam number of rows as columns
whether the rows have the sam number of elements
For instance:
[[1,2,3], [1,55,9]] has the same number of rows as columns - here 2 - and each row has the same number of elements namely 3.
But
[[1,2], [1,55], [4,7]] has the same number of elements in each row though it has unequal number of rows and columns namely 3r 2c.
yet another example:
[[1,2], [1,55], [4,7,8]] has neither the same number of rows as columns nor each row has the same number of elements.
Actually step 1 includes step 2, am I right??
My attempt:
So what I attempted so far, is this:
listIsEqual :: [[Int]] -> Bool
listIsEqual myList = (all (\x -> length x == (length myList)) )
Right now I get the following error mesage:
Couldn't match expected type `Bool' with actual type `[a0] -> Bool'
In the return type of a call of `all'
Probable cause: `all' is applied to too few arguments
In the expression: (all (\ x -> length x == (length myList)))
In an equation for `listIsEqual':
listIsEqual myList = (all (\ x -> length x == (length myList)))
Could anyone tell me where the problem is?
Is there also any other ways to solve this problem?
GHC's error messages aren't always the most helpful, but in this case it got it right.
Probable cause: `all' is applied to too few arguments
And indeed, you forgot the second argument to all:
listIsEqual myList = all (\x -> length x == length myList) myList
^^^^^^
For the second task, you can map the length of every row (the number of columns in that row) defining a function
let columnLengths rows = map length rows
Prelude> columnLengths [[1,2], [1,55], [4,7,8]]
[2,2,3]
Now that we have a list containing the lengths of the columns, we have to check whether they are all equal. The function nub in Data.List removes duplicates from a list.
let columnsLengthEqual = (==) 1 . length . nub . columnLengths
Or all together
let columnsLengthEqual = (==) 1 . length . nub . map length
Matrix respecting your criteria, are squared matrix then checking if the square of first 's row's length is equal to the number of element should be ok.
isSquaredMatrix xs#(h:_) = ((^2) . length $ h) == (length . concat $ xs)
isSquaredMatrix _ = True
But as it has been pointed out by hammar, this is incorrect since we can have positive outcome using wrong input.
# isSquaredMatrix [[1,2,3],[4,5],[6,7,8,9]]
True -- But this is false
#John,
we use # into pattern matching when we want to refer to the whole type at the same time we have break it down. An example should give you more insight,
Usually we can define an exhaustive function working on list using pattern matching as follow.
actOnList [] = -- do something when we encounter an empty list
actOnList (x:xs) = -- do something with h, and do another stuff with xs
For example,
actOnList [] = []
actOnList (x:xs) =
if (pred x)
then x:xs
else actOnList xs
Here my function consumme the list until a predicate is satisfied.
We can imagine skipUntilMeetAChar
skipUntilMeetAChar :: [Char] -> Char -> [Char]
skipUntilMeetAChar [] c = []
skipUntilMeetAChar (x:xs) c =
if (x==c)
then x:xs
else actOnList xs c
As you see when the char is met we'd like to return the list as it, not only the tail, then to do so we need to reconstruct our list using the head x and the tail xs. This can be overcome using #.
skipUntilMeetAChar :: String -> Char -> String
skipUntilMeetAChar [] c = []
skipUntilMeetAChar l#(x:xs) c =
if (x==c)
then l
else actOnList xs c
Now, regarding ($) operator, this is again some syntactic sugar.
As function application are left associative, this lead us to extensively use bracket to reorder the application of our function, as in the example below.
# f3 (f2 (f1 (f0 x)))
Then to avoid the pain of managing closing parentheses, dollars operator $ have been introduce and then our previous expression become.
# f3 $ f2 $ f1 $ f0 x
Which is definitely more readable and easiest to write.
Note that this operator is defined as follow.
($) :: (a -> b) -> a -> b
f $ x = f x
And I advise you to learn more about it consulting the following introduction material.

F# sorting array

I have an array like this,
[|{Name = "000016.SZ";
turnover = 3191591006.0;
MV = 34462194.8;};
{Name = "000019.SZ";
turnover = 2316868899.0;
MV = 18438461.48;};
{Name = "000020.SZ";
turnover = 1268882399.0;
MV = 7392964.366;};
.......
|]
How do I sort this array according to "turnover"? Thanks
(does not have much context to explain the code section? how much context should I write)
Assuming that the array is in arr you can just do
arr |> Array.sortBy (fun t -> t.turnover)
I know this has already been answered beautifully; however, I am finding that, like Haskell, F# matches the way I think and thought I'd add this for other novices :)
let rec sortData =
function
| [] -> []
| x :: xs ->
let smaller = List.filter (fun e -> e <= x) >> sortData
let larger = List.filter (fun e -> e > x) >> sortData
smaller xs # [ x ] # larger xs
Note 1: "a >> b" is function composition and means "create a function, f, such that f x = b(a(x))" as in "apply a then apply b" and so on if it continues: a >> b >> c >>...
Note 2: "#" is list concatenation, as in [1..100] = [1..12] # [13..50] # [51..89] # [90..100]. This is more powerful but less efficient than cons, "::", which can only add one element at a time and only to the head of a list, a::[b;c;d] = [a;b;c;d]
Note 3: the List.filter (fun e ->...) expressions produces a "curried function" version holding the provided filtering lambda.
Note 4: I could have made "smaller" and "larger" lists instead of functions (as in "xs |> filter |> sort"). My choice to make them functions was arbitrary.
Note 5: The type signature of the sortData function states that it requires and returns a list whose elements support comparison:
_arg1:'a list -> 'a list when 'a : comparison
Note 6: There is clarity in brevity (despite this particular post :) )
As a testament to the algorithmic clarity of functional languages, the following optimization of the above filter sort is three times faster (as reported by VS Test Explorer). In this case, the list is traversed only once per pivot (the first element) to produce the sub-lists of smaller and larger items. Also, an equivalence list is introduced which collects matching elements away from further comparisons.
let rec sort3 =
function
| [] -> []
| x::xs ->
let accum tot y =
match tot with
| (a,b,c) when y < x -> (y::a,b,c)
| (a,b,c) when y = x -> (a,y::b,c)
| (a,b,c) -> (a,b,y::c)
let (a,b,c) = List.fold accum ([],[x],[]) xs
(sort3 a) # b # (sort3 c)

Resources