I am doing homework for university and am facing a strange problem with the webassign portal (you put your code in and that one checks if everything is alright).
We need to write a function to multiply matrices. This is done step by step using vector multiplication, matrix mult vector, matrix mult matrix.
My code is running on smlnj interpreter, but not in webassign:
fun v_v_mult [] _ = 0.0
| v_v_mult _ [] = 0.0
| v_v_mult (r::rs) (c::cs) = r*c + v_v_mult rs cs
fun m_v_mult [] _ = []
| m_v_mult _ [] = []
| m_v_mult (rv::rvs) cs = v_v_mult rv cs :: m_v_mult rvs cs
So, everything is fine in my REPL, but webassign tells me that
m_v_mult [[]] []
raises an exception. I can't reproduce the exception in my REPL, as the above code works as expected.
Does pattern matching a list of an empty list need anything special? I searched stackoverflow, but found no hint. Can you give me a hint (or link or key word for better searching)?
Thanks,
Jochen
ok, guys, the answer is somewhat strange.
fun m_v_mult [] _ = []
| m_v_mult (rv::rvs) cs = v_v_mult rv cs :: m_v_mult rvs cs
which is, second line deleted.
That's because, m_v_mult [[]] [] has no empty matrix in the first argument, but a matrix with one row, which is empty. So the result should be a vector with one element, that includes the sum over 0 numbers. So the result should be the identity of the addition, which is 0. And you get this result by the last case, which calls v_v_mult, which returns 0 for that case.
I wouldn't have come to this solution without a hint of the teacher.
Thanks for helping think about that problem and telling me I am at least right in the way I coded it.
Related
I want to find all the possible partitions of a string into a list of non-empty strings.
For example if i give as input "sun",
i want to create this output : [["s","u","n"], ["s","un"], ["su","n"], ["sun"]].
I have created a simple function with recursion but it prints this overflow error i can't fix it please i need help:
partition :: String->[[String]]
partition w = [[(head w)]:fix | fix <- partition (tail w)]
++[((head w):fix):fixfix | (fix:fixfix)<-partition (tail w)]
The essential problem is that you're missing the base case for the recursion, so you have an infinite loop.
The simple thing is just to replace the head/tail mess with pattern matching, which will solve that problem as a side effect.
partition [] = [[]]
partition (w:ws) =
[[w]:fix | fix <- partition ws] ++
[(w:fix):fixfix | (fix:fixfix)<-partition ws]
This turns out to work okay, somewhat to my surprise. Why was I surprised? I figured that, with optimization, GHC would use common subexpression elimination to rewrite it to
partition [] = [[]]
partition (w:ws) =
[[w]:fix | fix <- partitionws] ++
[(w:fix):fixfix | (fix:fixfix)<-partitionws]
where partitionws = partition ws
That would be bad: it would save the entire partition ws calculation across the ++, using lots of memory. But it seems GHC is clever enough these days not to do that.
To be more confident, you can avoid the common subexpression, by accumulating a "continuation" explaining how you'll process each element you produce.
part :: ([[a]] -> [b]) -> [a] -> [b]
part f [] = f []
part f (w:ws) =
part (\fix -> f ([w]:fix)) ws ++
part (\q -> case q of
[] -> []
fix:fixfix -> f ((w:fix):fixfix)) ws
partition = part (:[])
For reasons I don't know, this version is a couple times faster than the simple one.
If you don't care about the order in which the elements are produced, you can avoid the space leak risk much more simply (and perhaps even faster) by doing something like this:
partition [] = [[]]
partition (w:ws) =
[ q
| m <- partition ws
, q <- ([w]:m) : [(w:fix):fixfix | fix:fixfix <- [m]]]
This is almost as simple as the simplest solution.
I have just started my F# adventure and am stuck. I want to write a recursive function that takes the elements from a list, add them in pairs and returns the list - int list->(int*int) list
So like this:
[x1; x2; x3; x4] = [(x1,x2);(x3,x4)]
This is what I have right now.
let rec combinePair xs =
match xs with
|[] -> []
|[x] -> [x]
|x::y::xs' -> (x,y)::combinePair xs'
This does not work, but I feel it may be close to the answer. I just don't how to continue from here. As I am still trying to learn I hoped that maybe one could point me in the right direction instead of giving me the full answer
Cheers
I was very close to the answer. I forgot to add what would happen in cases of the list containing an odd number of elements. In my case I just wanted it to get rid of the last element. This is the solution
let rec combinePair xs =
match xs with
| [] -> []
| [x] -> []
| x::y::xs' -> (x,y)::combinePair xs'
I am currently working on a ML small project and learning how to work with it, but here are some problems that I'm facing but cannot find any source online.
I want to have a function to return the last number of the list, which is a real number list. I wrote a code to return a single element real list, but i will it to be a real number but not a list. here is my code:
fun last [] = nil
| last(head::nil) = [head]
| last(head::list) = last(list)
I thought
last(head::nil)=head
would help get the real number but it just give me an error that:
operator domain: 'Z list list
operand: real list
Thank you!
As melpomene says, nil isn't a value of type real, so it can't be the return type for the empty list. In fact, no value can be returned, because the list is empty! This makes the function last partial. You want to avoid partial functions, because they may crash at runtime. You can define an alternative function, lastOpt:
fun lastOpt [] = NONE
| lastOpt [x] = SOME x
| lastOpt (_::xs) = lastOpt xs
For example,
- lastOpt [1,2,3];
> val it = SOME 3 : int option
- lastOpt [];
> val it = NONE : 'a option
This passes responsibility for handling empty lists explicitly to the caller of lastOpt.
The built-in function List.last was made unsafely with exceptions:
fun last [] = raise Empty
| last [x] = x
| last (_::xs) = last xs
I wouldn't recommend using this.
So i just got in ML programming and I found this excercise in a book. The excercise says to build a recursive function that takes an integer and a list. If L=[a1,a2,a3] then the desired result is [ai+1,ai+2,...,an,a1,a2,...,ai]. So I wrote a function and after a lot of hours I narrowed the errors down to one which I can't understand. Here is my function:
fun cycle L i =
if i = 0 then L
else (cycle tl(L) (i-1)) # [hd(L)];
I will upload an image with the error that i get so someone can explain to me what the interpreter is trying to say to me.
The numbers next to the "a" just show the order of these elements in the list.So for L=[1,2,3,4,5] and for i = 2, the desire result is the List L=[3,4,5,1,2]. I don't think that the type of list is essential in this problem. Hope this further explanation helped
It's a syntactic problem with the recursive call cycle tl(L) (i-1).
In SML, the syntax for function application is juxtaposition, not parentheses. In your case tl(L) indeed calls the function tl with argument L, but that's equivalent to just tl L. The parentheses are redundant and, as such, ignored.
Now, if you replace the minimal version within your original call, you'll get this: cycle tl L (i-1). It's calling cycle with three arguments, instead of just two.
The correct way of writing it would be: cycle (tl L) (i-1).
Ionuț already gave a sufficient answer to the syntax problem; here are some further suggestions:
Use pattern matching rather than hd and tl.
Consider the base cases; what are the simplest sub-problems you can think of? E.g. cycling the empty list will always give the empty list regardless of n, and cycling L 0 times will always give L back. Having both base cases as patterns helps.
Consider the recursive case; the top element (assuming it exists) is cycled and i is reduced by one, until eventually i is 0 or L is empty. Because the second base case catches the empty list, we can freely assume that L is non-empty here, in which case it will match the pattern x::xs.
fun cycle 0 xs = xs
| cycle i [] = []
| cycle i (x::xs) = cycle (i-1) (xs # [x])
Depending on whether 0 <= i and i <= length xs are preconditions for the function or not, you may want to handle these once before activating the main recursion, e.g. by wrapping the function above:
fun cycle i ys =
let fun fun cycle' 0 xs = xs
| cycle' i [] = []
| cycle' i (x::xs) = cycle' (i-1) (xs # [x])
in
if 0 <= i andalso i <= length xs
then cycle' i ys
else raise Domain
end
The main operation, namely xs # [x] is terribly inefficient, since its running time is proportional to the length of xs and is activated n times. So the running time of cycle becomes O(n • |L|) when something like O(min(n,|L|)) should be achievable.
You could probably make a much faster version if you store the cycled elements in a separate list, without using #, and combine the remaining elements with this list after the elements have been cycled. Depending on what you felt about 0 <= i and i <= length xs, you may run into problems with the following test case:
val cycle_test_1 = (cycle 5 [1,2,3,4] = [2,3,4,1])
I seem to be struggling with something that should be extremely simple in Haskell, but I just cannot figure it out and I need some help. I am trying to convert a list of integers ([3,2,1]) and convert it to a single integer (321).
Here is what I have so far:
fromDigits :: [Integer] -> Integer
fromDigits [] = 0;
fromDigits (x:xs) = x : fromDigits (xs)
What am I doing wrong?
You can use the worker wrapper approach to do this:
fromDigits :: [Integer] -> Integer
fromDigits xs = aux xs 0
where aux [] acc = acc
aux (x:xs) acc = aux xs ((acc * 10) + x)
Demo:
λ> fromDigits [3,2,1]
321
Or even you can use the higher order function foldl:
λ> foldl' (\acc x -> (acc * 10) + x) 0 [1,2,3]
123
This is not a conversion. The list [3,2,1] may “look” like the number 321, but it's not a one-to-one relation (as Greg alluded – [32,1] looks like the same number), and most certainly not a canonical one (why would you use base 10? Is this actually hexadecimal?) Hence there is really no reason why this should be particularly simple in Haskell1. This is not JavaScript, fortunately.
Repeat of message... it looks like the number 321, and that's all, it's not related to the number in really any meaningful way. So, if you really need to implement this function of questionable worth (I think you shouldn't), then you might as well do the hack to actually exploit the “looks like” thing. I.e.,
fromDigits = read . filter (not . (`elem`"[,]")) . show
This uses the Show instance of lists, to convert the list [3,2,1] into an actual string "[3,2,1]", then throws away the list-related characters, and reads the concatenated string "321" back, yielding the number 321.
1Apart from the fact that it's generally quite simple to implement pure functions in Haskell...