Elm : How to apply List.map on Nested List - nested-lists

This is the basic work i have done with simple List Float
renderCoordinates : List Float -> Html Msg
renderCoordinates coordinates =
ol [ type_ "A"]
(List.map (\coordinate -> li [] [text (String.fromFloat coordinate)]) coordinates)
When it comes to List (List(List Float)) and i am stuck. I am wonder if i can do it this way?
renderCoordinates : List (List(List Float)) -> Html Msg
renderCoordinates coordinates =
ol [ type_ "A"]
(List.map (List.map (\coordinate -> li [] [text (String.fromFloat coordinate)]) ) coordinates)
-- List.map (List.map (List.map (\coordinate -> li [] [text (String.fromFloat coordinate)]) ) ) coordinates doesnt work as well
Basically i wish to display each items in the list of List (List(List Float))...
Any help is appreciate !
Updates
With the help of #Simon
I made some modification of code to make it works like :
renderCoordinates : List (List (List Float)) -> Html Msg
renderCoordinates coordinates =
let
map1 : List (List (List Float)) -> List (Html Msg)
map1 lists =
List.concatMap map2 lists
map2 : List (List Float) -> List (Html Msg)
map2 floats =
List.map (\coordinate -> li [] [ text (Debug.toString coordinate) ]) floats
in
ol [ type_ "A" ]
(map1 coordinates)
This will print A: [X, Y]

You need to do it in parts and concat the results at each stage
renderCoordinates : List (List (List Float)) -> Html Msg
renderCoordinates coordinates =
let
map1 : List (List Float) -> List (Html Msg)
map1 lists =
L.concatMap map2 lists
map2 : List Float -> List (Html Msg)
map2 floats =
List.map (\coordinate -> li [] [ text (String.fromFloat coordinate) ]) floats
in
ol [ type_ "A" ]
(List.concatMap map1 coordinates)

Related

purescript halogen - render elements or nothing conditionally

I have a utility function to conditinally render elements:
thanRender :: ∀ w i. Boolean -> EL.HTML w i -> EL.HTML w i
thanRender true h = h
thanRender _ _ = EL.text ""
Usage:
isJust state.foo `thanRender` (EL.h1_ [ EL.text state.title ])
Is there a better way to "render nothing" as to render EL.text "" ?

How to implement `Show` interface for parameterized tuple?

I have Coord function that transforms an n-dimensional size to the type of coordinates bounded by given size: Coord [2,3] = (Fin 2, Fin 3).
import Data.Fin
import Data.List
Size : Type
Size = List Nat
Coord : Size -> Type
Coord [] = ()
Coord s#(_ :: _) = foldr1 (,) $ map Fin s
How can I implement Show interface for Coord s?
If I understand it correctly, the problem is that with s erased at compile time there is no way to know what the actual type of Coord s is. So my best attempt is this abomination:
show' : {s : Size} -> Coord s -> String
show' {s=[]} = show
show' {s=[_]} = show
show' {s=[_,_]} = show
show' = ?show'_rhs
{s : Size} -> Show (Coord s) where
show = show'
foo : {s : Size} -> Coord s -> String
foo x = show' x -- compiles and works
foo x = show x -- error
Error: While processing right hand side of foo. Can't find an implementation for Show (Coord s).
22 | foo : {s : Size} -> Coord s -> String
23 | foo x = show' x
24 | foo x = show x
^^^^^^
(,) already has a Show implemention. Coords is just an alias not a datatype, it can't have separate interface implementations.

NetLogo nested list items to character seperated string

I have a triple nested list:
[
[
[a b]
[c d]
...
]
[
[e f]
[g h]
...
]
]
I want a string with the format a,c,... respectively e,g,..
My current approach is to first make a new list with as much items as the first nested list has and add the first items of the lists within said list.
Afterwards then new list is reduced:
let nl ( n-values ( length ( item 0 list) ) [ i -> ( item 0 ( item i ( item 0 list)) ) ] )
reduce [ [a b] -> (word a "," b) ] nl
Is there a better way to do this, as in this approach it is very difficult to maintain the overview of the "denesting" of the list.
Assuming your list looks like:
let a ( list ( list [ "a" "b" ] [ "c" "d" ] ) ( list [ "e" "f" ] [ "g" "h" ] ) )
I'm not sure that this makes it easier to keep track of the denesting, but you could nest a map within another to get the order you want:
print map [ x -> map [ y -> item 0 y ] x ] a
If you want it as a list of strings with commas, I like the csv:to-row primitive from the csv extension:
print map [ x -> csv:to-row map [ y -> item 0 y ] x ] a
Again, not sure that it's more straightforward but it's an alternative approach!
Edit:
As Seth pointed out, map [ y -> item 0 y ] can be replaced with map first- so the modified versions would look like:
print map [ x -> map first x ] a
and
print map [ x -> csv:to-row map first x ] a
Thanks Seth!

Scala: Add a sequence number to duplicate elements in a list

I have a list and want to add a sequential number to duplicate elements.
val lst=List("a", "b", "c", "b", "c", "d", "b","a")
The result should be
List("a___0", "b___0", "c____0", "b___1", "c____1", "d___0", "b___2","a___1")
preserving the original order.
What I have so far:
val lb=new ListBuffer[String]()
for(i<-0 to lst.length-2) {
val lbSplit=lb.map(a=>a.split("____")(0)).distinct.toList
if(!lbSplit.contains(lst(i))){
var count=0
lb+=lst(i)+"____"+count
for(j<-i+1 to lst.length-1){
if(lst(i).equalsIgnoreCase(lst(j))) {
count+=1
lb+= lst(i)+"____"+count
}
}
}
}
which results in :
res120: scala.collection.mutable.ListBuffer[String]
= ListBuffer(a____0, a____1, b____0, b____1, b____2, c____0, c____1, d____0)
messing up the order. Also if there is a more concise way that would be great.
This should work without any mutable variables.
val lst=List("a", "b", "c", "b", "c", "d", "b","a")
lst.foldLeft((Map[String,Int]().withDefaultValue(0),List[String]())){
case ((m, l), x) => (m + (x->(m(x)+1)), x + "__" + m(x) :: l)
}._2.reverse
// res0: List[String] = List(a__0, b__0, c__0, b__1, c__1, d__0, b__2, a__1)
explanation
lst.foldLeft - Take the List of items (in this case a List[String]) and fold them (starting on the left) into a single item.
(Map[String,Int]().withDefaultValue(0),List[String]()) - In this case the new item will be a tuple of type (Map[String,Int], List[String]). We'll start the tuple with an empty Map and an empty List.
case ((m, l), x) => - Every time an element from lst is passed in to the tuple calculation we'll call that element x. We'll also receive the tuple from the previous calculation. We'll call the Map part m and we'll call the List part l.
m + (x->(m(x)+1)) - The Map part of the new tuple is created by creating/updating the count for this String (the x) and adding it to the received Map.
x + "__" + m(x) :: l - The List part of the new tuple is created by pre-pending a new String at the head.
}._2.reverse - The fold is finished. Extract the List from the tuple (the 2nd element) and reverse it to restore the original order of elements.
I think a more concise way that preserves the order would just to be to use a Map[String, Int] to keep a running total of each time you've seen a particular string. Then you can just map over lst directly and keep updating the map each time you've seen a string:
var map = Map[String, Int]()
lst.map { str =>
val count = map.getOrElse(str, 0) //get current count if in the map, otherwise zero
map += (str -> (count + 1)) //update the count
str + "__" + count
}
which will give you the following for your example:
List(a__0, b__0, c__0, b__1, c__1, d__0, b__2, a__1)
I consider that easiest to read, but if you want to avoid var then you can use foldLeft with a tuple to hold the intermediate state of the map:
lst.foldLeft((List[String](), Map[String, Int]())) { case ((list, map), str) =>
val count = map.getOrElse(str, 0)
(list :+ (str + "__" + count), map + (str -> (count + 1)))
}._1

Implementing sequences of sequences in F#

I am trying to expose a 2 dimensional array as a sequence of sequences on an object(to be able to do Seq.fold (fun x -> Seq.fold (fun ->..) [] x) [] mytype stuff specifically)
Below is a toy program that exposes the identical functionality.
From what I understand there is a lot going on here, first of IEnumerable has an ambiguous overload and requires a type annotation to explicitly isolate which IEnumerable you are talking about.
But then there can be issues with unit as well requiring additional help:
type blah =
class
interface int seq seq with
member self.GetEnumerator () : System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<(int*int)>> =
seq{ for i = 0 to 10 do
yield seq { for j=0 to 10 do
yield (i,j)} }
end
Is there some way of getting the above code to work as intended(return a seq<seq<int>>) or am I missing something fundamental?
Well for one thing, GetEnumerator() is supposed to return IEnumerator<T> not IEnumerable<T>...
This will get your sample code to compile.
type blah =
interface seq<seq<(int * int)>> with
member self.GetEnumerator () =
(seq { for i = 0 to 10 do
yield seq { for j=0 to 10 do
yield (i,j)} }).GetEnumerator()
interface System.Collections.IEnumerable with
member self.GetEnumerator () =
(self :> seq<seq<(int * int)>>).GetEnumerator() :> System.Collections.IEnumerator
How about:
let toSeqOfSeq (array:array<array<_>>) = array |> Seq.map (fun x -> x :> seq<_>)
But this works with an array of arrays, not a two-dimensional array. Which do you want?
What are you really out to do? A seq of seqs is rarely useful. All collections are seqs, so you can just use an array of arrays, a la
let myArrayOfArrays = [|
for i = 0 to 9 do
yield [|
for j = 0 to 9 do
yield (i,j)
|]
|]
let sumAllProds = myArrayOfArrays |> Seq.fold (fun st a ->
st + (a |> Seq.fold (fun st (x,y) -> st + x*y) 0) ) 0
printfn "%d" sumAllProds
if that helps...
module Array2D =
// Converts 2D array 'T[,] into seq<seq<'T>>
let toSeq (arr : 'T [,]) =
let f1,f2 = Array2D.base1 arr , Array2D.base2 arr
let t1,t2 = Array2D.length1 arr - f1 - 1 , Array2D.length2 arr - f2 - 1
seq {
for i in f1 .. t1 do
yield seq {
for j in f2 .. t2 do
yield Array2D.get arr i j }}
let myArray2D : string[,] = array2D [["a1"; "b1"; "c1"]; ["a2"; "b2"; "c2"]]
printf "%A" (Array2D.toSeq myArray2D)