Having trouble reading (interpreting) this functional Miranda code.
g = (foldr (+) 0) . (foldr ((:) . ((#) . (:[]))) [])
I know what it does
Calculate the size of a list by taking the length via #
Creating a one element list containing the above length of the original input list
Collapsing the new list using foldr into a single integer with the operation +0 on each element
However I am confused by the brackets and don't see where the input list is fed in. What does the rightmost [] constructor do?
Also why does this code only work via the function g, but if I call it directly it throws an error?
In short, g is a function that returns the length of the list.
Let's break the function into some parts.
|| returns 1 for any input.
|| return_one "hoobar" = 1
return_one :: * -> num
return_one = (#) . (:[])
|| ignore first argument, insert 1 to the second argument.
|| insert_one "hoobar" [4,5,6] = [1,4,5,6]
insert_one :: *->[num]->[num]
insert_one = (:) . return_one
|| sum of list.
|| sum_list [7,8,9] = 24
sum_list :: [num] -> num
sum_list = foldr (+) 0
|| generate list of 1 which as the same length of original list.
|| change_one ["apple","banana"] = [1,1]
change_one :: [*] -> [num]
change_one = foldr insert_one []
|| return the length of the list.
|| g ["apple","banana"] = 2
g :: [*] -> num
g = sum_list . change_one
I would explain some confusing functions.
return_one
(:[]) is a function that creates single element list, and (#) returns the length.
Strictly speaking, (:[]) is (:) which takes [] as first argument.
therefore (:[]) "hoobar" = "hoobar":[] = ["hoobar"], and applying (#) to it returns 1.
change_one
It starts with empty list [] and traverses through the list with inserting 1 to the front.
foldr insert_one [] ["apple","banana"]
= foldr insert_one [1] ["apple"]
= foldr insert_one [1,1] []
I don't know Miranda too well, but based on Haskell (I believe the differences between the two here would be minor, with only the # being a unary operator for list length being the only semi-significant one and with || being the comment syntax): The . is function composition:
(p . q) x = p (q x)
|| also can be written as:
p . q = \x -> p (q x)
Function composition is an associative operation, so p . (q . r) = (p . q) . r = p . q . r.
Using this information, we can expand this with the definition of .:
g = (foldr (+) 0) . (foldr ((:) . ((#) . (:[]))) []) || Original definition
g list = foldr (+) 0 (foldr ((:) . ((#) . (:[]))) [] list)
g list = foldr (+) 0 (foldr (\x -> (:) (((#) . (:[])) x)) [] list)
g list = foldr (+) 0 (foldr (\x -> (:) ((\y -> (#) ((:[]) y)) x)) [] list)
This can be cleaned up some more:
g list = foldr (+) 0 (foldr (\x -> (:) ((\y -> (#)(y:[])) x)) [] list) || More conventional operator syntax for the innermost `:`
g list = foldr (+) 0 (foldr (\x -> (:) ((#)(x:[]))) [] list) || Innermost lambda was applied to x. Substitute y for x.
g list = foldr (+) 0 (foldr (\x -> (:) ((#)([x]))) [] list) || Apply innermost `:`
g list = foldr (+) 0 (foldr (\x -> (:) #[x])) [] list) || Remove unnecessary parentheses
g list = foldr (+) 0 (foldr (\x acc -> (:) (#[x]) acc) [] list) || Explicitly write implicit argument. This particular step is called eta-expansion
g list = foldr (+) 0 (foldr (\x acc -> (:) 1 acc) [] list) || #[x] is always 1, no matter what x is
g list = foldr (+) 0 (foldr (\x acc -> 1 : acc) [] list) || More conventional syntax for `:`
Also note that the foldr doesn't apply +0 to every element, as you've stated in the question. foldr op z (a:b:c:[]) becomes op a (op b (op c z))) (a:b:c:[] is another way to write [a,b,c]). I always thought this diagram is helpful to understand that:
Additionally, most likely the reason that you got an error when calling it directly is that p . q x is not the same as (p . q) x.
Related
I am very new to Haskell and I wrote a Data Type in Haskell
for representing an interval map.
What does that mean? Briefly: A map data type that gives you a value back
for every possible key (put simply in my case [0..]).
Then you insert "sequences" like I want my map to hold from 7 to 23 'b'
so keys 0 to 6 will be init value e.g. 'a' and 7 to 23 will be 'b' and 24 and ongoing will be 'a' again etc.
I managed to wrote the Data Type, a get and insert function as well as a
functor version.
But I can't managed to get a applicative functor version to work.
The idea is to set the keys value to [0..] and just work on the values.
Here is my code and thanks for any provided help!
-- Building an interval map data structure in haskell
data IntervalMap k v = IntervalMap {keys :: [k] , values :: [v]} | Empty deriving Show
-- k = key, Typ variable
-- v = value, Typ variable
singleton :: (Enum k, Num k) => v -> IntervalMap k v
singleton v = IntervalMap{keys=[0..], values= repeat v}
-- get operator => a ! 5 = value at position 5
(!) :: Ord k => IntervalMap k v -> k -> v
(!) iMap k = snd (head (filter (\(x, y) -> x == k) (zip (keys iMap) (values iMap)) ))
-- insert a sequence into intervalMap
insert :: (Ord k, Num k, Enum k) => k -> k -> v -> IntervalMap k v -> IntervalMap k v
insert start end value iMap = IntervalMap {keys=keys iMap, values = rangeChanger (values iMap) start end value}
-- helper function to change a range of values in an intervalMap
rangeChanger :: (Num a1, Enum a1, Ord a1) => [a2] -> a1 -> a1 -> a2 -> [a2]
rangeChanger iMapValues start end value = [if (i >= start) && (i <= end) then newValue else iMapValue | (iMapValue, newValue, i) <- zip3 iMapValues (repeat value) [0..]]
-- functor instance for intervalMap
instance Functor (IntervalMap k) where
-- fmap :: (a -> b) -> f a -> f b
fmap f iMap = IntervalMap {keys=keys iMap, values= map f (values iMap) }
-- applicative functor for intervalMap
instance (Ord k, Num k, Enum k) => Applicative (IntervalMap k) where
pure k = IntervalMap{keys=[0..], values=repeat k}
_ <*> Nothing = Nothing
-- HOW TO DO?
-- class Functor functor => Applicative functor where
-- pure :: a -> functor a
-- (<*>) :: functor (a -> b) -> functor a -> functor b
-- (*>) :: functor a -> functor b -> functor b
-- (<*) :: functor a -> functor b -> functor a
It seems like you always expect the keys to be [0..], e.g. it is hard-coded in your rangeChanger function. If that is the case then it is redundant and honestly I would leave it out. You can easily reconstruct it by doing something like zip [0..] (values iMap) as you do in the rangeChanger function.
If you make that change, then your IntervalMap data structure is basically the same as ZipList which has an applicative instance here:
instance Applicative ZipList where
pure x = ZipList (repeat x)
liftA2 f (ZipList xs) (ZipList ys) = ZipList (zipWith f xs ys)
You see that this doesn't define a <*> but that can be defined in terms of liftA2: p <*> q = liftA2 (\f x -> f x) p q, so you could also write that explicitly for ZipList:
ZipList fs <*> ZipList xs = ZipList (zipWith (\f x -> f x) fs xs)
Edit: I should also mention that one difference with ZipList is that you have an Empty constructor for your IntervalMap type. That makes things harder, you would need to know that your values have some sort of default value, but that is not possible in general (not every type has a default value), so your type cannot be an Applicative. Do you really need that Empty case?
I am a new to SML and I want to write a function splitup : int list -> int list * int list that given a list of integers creates from two lists of integers, one containing the non-negative entries, the other containing the negative entries.
Here is my code :
fun splitup (xs :int list) =
if null xs
then ([],[])
else if hd xs < 0
then hd xs :: #1 splitup( tl xs)
else hd xs :: #2 splitup( tl xs)
Here's the warning i get:
ERROR : operator and operand don't agree
ERROR : types of if branches do not agree
The function splitup(tl xs) should return int list * int list so i think my recursion should be all right.
What is the problem and how can i fix it ?
The problem is that
hd xs :: #1 splitup( tl xs)
and
hd xs :: #2 splitup( tl xs)
are lists – you can tell from the :: – not pairs of lists as the result should be.
For the non-empty case, you need to first split the rest of the list, then attach the head to the correct part of the result and add it the other part of the result in a pair.
It's also a good idea to get used to pattern matching, as it simplifies code lot.
Something like this:
fun splitup [] = ([], [])
| splitup (x::xs) = let (negatives, non_negatives) = splitup xs
in if x < 0
then (x :: negatives, non_negatives)
else (negatives, x :: non_negatives)
end
There is already List.partition: ('a -> bool) -> 'a list -> 'a list * 'a list, a higher-order library function that does this. In case you want to split up integers into (negative, non-negative):
val splitup = List.partition (fn x => x < 0)
I am new to Ocaml and want help with recursive function defined on a recursive data type. I have defined a data type as follows
type 'a slist = S of 'a sexp list
and
'a sexp = Symbol of 'a | L of 'a slist
The function(subst) I'm writing checks for a symbol a in the defined slist and substitutes it by b. For ex subst 1 10 S[ 1; 4; S[L[3; 1;]; 3];] returns S[10; 4; S[L[S[3; 10;]]; 3;]
. My code is as follows
let rec subst a b sl = match sl with
S s -> match s with
[] -> []
| p :: q -> match p with
Symbol sym -> if sym = a then S[b] :: (**subst** a b S[q]) else
S[p] :: (subst a b S[q])
L l -> (subst a b l) :: (subst a b S[q])
| L lis -> subst a b lis;;
I am getting the error :
This function is applied to too many arguments; Maybe you forgot a ';'
Please help
Your type can be defined in a simpler way, you don't need slist:
type 'a sexp = Symbol of 'a | L of 'a sexp list
Your problem is that subst a b S[q] is read as subst a b S [q], that is the function subst applied to 4 arguments. You must write subst a b (S[q]) instead.
Basically the function will take one parameter as a character, number and check whether it is inside the List or not ?
let rec (member: a -> List a -> Bool) x =
| [] -> False
| Cons y ys -> if x == y then True else member x ys
;;
I got the solution but it seems too vague.
Could anyone show me how to use Cons operator in this particular case ?
Thanks
In Ocaml, the cons operator is ::. But it is not the only problem of your piece of code.
Here your function takes only one argument (x) but you use it with two (member x ys), you wanted to do let rec member x l = match l with or let rec member x = function which is equivalent.
In OCaml you don't have to give the type of your values, but if you do, this is not the rigth syntax. OCaml types are not capitalized, type parameters start with '
and are placed before the type they parameterize, then the type of your function is 'a -> 'a list -> bool. Moreover, for a function you have to give the type of the parameters and the return type separately (let rec member (x : 'a) (l : 'a list) : bool =).
The operator for equality is = and not ==.
Even if it is correct, don't use if then else to return a boolean, logical operators || and && should be used instead.
Corrected code:
let rec member x = function
| [] -> false
| y :: ys -> x = y || member x ys
I am trying to write a general function in F# that would return all the permutations of a list. I was trying to accomplish this using a recursive algorithm inspired by the java version here
But on the final line of the recursive function, I get the error given in the comments. I am guessing this is something to do with collating the output produced when the recursive loop exits (the output of if(Array.length <= 1) then being executed) with the rest Array.Map function.
I would greatly appreciate it if someone could give an explanation of why this error is happening and how I can go about fixing it.
let GetPermutationsOfList inputList =
let rec innerLoop firstPart secondPart =
if (Array.length secondPart) <= 1 then
[| Array.append firstPart secondPart |]
else
let SliceAtMarkerElement m =
let currentMarkerElement = secondPart.[m]
let everythingBeforeMarkerElement = secondPart.[0 .. m - 1]
let everythingAfterMarkerElement = secondPart.[m+1 .. ]
let newSecondPartList = Array.append everythingBeforeMarkerElement everythingAfterMarkerElement
let newFirstPartList = Array.append firstPart [|currentMarkerElement|]
(newFirstPartList, newSecondPartList)
[|for i in 0 .. ((Array.length secondPart) - 1) -> i|] |>
Array.map(fun c -> SliceAtMarkerElement c) |>
// The following line gives the error
// "Type Mismatch. Expecting a 'a but given a 'a[] The resulting type would be infinite when unifying "a' and "a[]"
Array.map(fun d -> innerLoop (fst d) (snd d))
innerLoop Array.empty (List.toArray inputList)
Assume that your function's indentation is correct, the error message is quite informative. In the innerLoop function, Array.append firstPart secondPart should return 'b []. However, the last line Array.map(fun d -> innerLoop (fst d) (snd d)) forces it to return 'b [] [], which couldn't be unified with 'b [].
I think you would like calculate permutations in each innerLoop and concatenate these results afterwards. You have to use Array.collect instead of Array.map:
[|for i in 0 .. (Array.length secondPart)-1 -> i|]
|> Array.map (fun c -> SliceAtMarkerElement c)
|> Array.collect (fun d -> innerLoop (fst d) (snd d))
The above fragment is employing two temporary arrays, which is wasteful. You can eliminate these extra arrays by using computation expression only:
[| for i in 0 .. (Array.length secondPart)-1 do
let first, second = SliceAtMarkerElement i
yield! innerLoop first second (* concatenating results *)
|]
UPDATE:
As clarified in the comment, you want to return an array of arrays where each array is a permutation. So your change would work and map operations should be:
[| for i in 0 .. (Array.length secondPart)-1 do
let first, second = SliceAtMarkerElement i
yield innerLoop first second (* returning each array as a permutation *)
|]