How to create triangle mesh from list of points in Elm - elm

Lets say I have a list of points
[p1,p2,p3,p4,p5,p6, ...] or [[p1,p2,p3,...],[...]...]
were p1,p2,p3 are one stripe and p4,p5,p6 the other.
p1 - p4 - p7 ...
| / | / |
p2 - p5 - p8 ...
| / | / |
p3 - p6 - p9 ...
. . .
. . .
. . .
How can I transform this into a list of
[(p1,p2,p4), (p4,p5,p2), (p2,p3,p5), (p5,p6,p3), ...]
Is there a way without converting the list into an Array und use get and handle all the Maybes

First let's define how to split a square into two triangles:
squareToTriangles : a -> a -> a -> a -> List (a, a, a)
squareToTriangles topLeft botLeft topRight botRight =
[ (topLeft, botLeft, topRight)
, (topRight, botRight, botLeft)
]
Now, since squares are made of two lists, let's assume you can use a list of tuples as input. Now you can make triangles out of lists of left/right points:
triangles : List (a, a) -> List (a, a, a)
triangles list =
case list of
(tl, tr) :: ((bl, br) :: _ as rest) ->
List.append
(squareToTriangles tl bl tr br)
(triangles rest)
_ ->
[]
Of course, your input doesn't involve tuples, so let's define something that takes a list of lists as input:
triangleMesh : List (List a) -> List (a, a, a)
triangleMesh list =
case list of
left :: (right :: _ as rest) ->
List.append
(triangles <| List.map2 (,) left right)
(triangleMesh rest)
_ ->
[]
Now you can pass in your list of lists, such that:
triangleMesh [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
-- yields...
[(1,2,4),(4,5,2),(2,3,5),(5,6,3),(4,5,7),(7,8,5),(5,6,8),(8,9,6)]
Note that this can probably be optimized by using a better method than List.append, but the general algorithm holds.

You can simply pattern match on your list as follows:
toMesh: List Float -> List (Float, Float, Float)
toMesh list =
case list of
[ p1, p2, p3, p4, p5, p6] ->
Just [(p1,p2,p4), (p4,p5,p2), (p2,p3,p5), (p5,p6,p3)]
_ ->
[]

Related

How to use interfaces with 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
I'd like to use show and other functions like (==) with Coord s:
foo : Coord s -> String
foo x = show x
Error: While processing right hand side of foo. Can't find an implementation for Show (Coord s).
22 | foo : Coord s -> String
23 | foo x = show x
^^^^^^
Earlier I tried to implement Show (Coord s), but looks like it's impossible. Here is linked question about it.
You can make your own list like data type:
data Coords : List Nat -> Type where
Nil : Coords []
(::) : Fin x -> Coords xs -> Coords (x :: xs)
toList : Coords xs -> List Nat
toList [] = []
toList (x::xs) = finToNat x :: toList xs
example : Coords [2, 3]
example = [1, 2]
Show (Coords xs) where
show cs = show $ toList cs
You can also try using Data.Vect.Quantifiers.All or Data.List.Quantifiers.All:
import Data.Vect
import Data.Vect.Quantifiers
example : All Fin [1, 2, 3]
example = [0, 1, 2]
-- not sure why this is isn't included with Idris
export
All (Show . p) xs => Show (All p xs) where
show pxs = "[" ++ show' "" pxs ++ "]"
where
show' : String -> All (Show . p) xs' => All p xs' -> String
show' acc #{[]} [] = acc
show' acc #{[_]} [px] = acc ++ show px
show' acc #{_ :: _} (px :: pxs) = show' (acc ++ show px ++ ", ") pxs
string : String
string = show example

Morphism where the algebra receives the item's position

Which one is the appropriate morphism (recursion scheme) to use when the given item's position (index, or path) is required in the transformer function?
A simple example would be transforming a list ["foo", "bar", "qux"] into the string "foo, bar, and qux". The current element's position is needed to know when to insert the and.
You need to make the index part of the structure so it is available to the recursion scheme. An ad-hoc way to do this is to define a foldWithIndex function:
foldWithIndex :: (Foldable t, Num i) => (i -> a -> b -> b) -> b -> t a -> b
foldWithIndex f z t = snd $ foldr f' (0, z) t
where
f' z (i, x) = (i + 1, f i z x)
This function takes an operator for combining the elements which also considers the index:
foldWithIndex combine "" ["foo", "bar", "qux"]
where
combine 0 s1 s2 = s1 ++ s2
combine 1 s1 s2 = s1 ++ " and " ++ s2
combine _ s1 s2 = s1 ++ ", " ++ s2
results in "foo, bar and qux".
For a more general approach see Data.Foldable.WithIndex, which provides a foldable typeclass that also takes an index into account.

Partition list into more than 2 parts

So I want to partitision a List ItemModel in Elm into List (List ItemModel). List.partition only makes the list into two lists.
I wrote some code that makes the list into the parts I want (code below).
But it's not as nice of a solution as I'd like, and since it seems like an issue many people would have, I wonder are there better examples of doing this?
partition : List (ItemModel -> Bool) -> List ItemModel -> List (List ItemModel)
partition filters models =
let
filterMaybe =
List.head filters
in
case filterMaybe of
Just filter ->
let
part =
Tuple.first (List.partition filter models)
in
part :: (partition (List.drop 1 filters) models)
Nothing ->
[]
The returned list maps directly from the filters parameter, so it's actually pretty straightforward to do this using just List.map and List.filter (which is what you're really doing since you're discarding the remainder list returned from List.partition):
multifilter : List (a -> Bool) -> List a -> List (List a)
multifilter filters values =
filters |> List.map(\filter -> List.filter filter values)
Repeated partitioning needs to use the leftovers from each step as the input for the next step. This is different than simple repeated filtering of the same sequence by several filters.
In Haskell (which this question was initially tagged as, as well),
partitions :: [a -> Bool] -> [a] -> [[a]]
partitions preds xs = go preds xs
where
go [] xs = []
go (p:ps) xs = let { (a,b) = partition p xs } in (a : go ps b)
which is to say,
partitions preds xs = foldr g (const []) preds xs
where
g p r xs = let { (a,b) = partition p xs } in (a : r b)
or
-- mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
partitions preds xs = snd $ mapAccumL (\xs p -> partition (not . p) xs) xs preds
Testing:
> partitions [ (<5), (<10), const True ] [1..15]
[[1,2,3,4],[5,6,7,8,9],[10,11,12,13,14,15]]
unlike the repeated filtering,
> [ filter p xs | let xs = [1..15], p <- [ (<5), (<10), const True ]]
[[1,2,3,4],[1,2,3,4,5,6,7,8,9],[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]]

Elm: Split list into multiple lists

I'd like to be able to split a list up into multiple lists.
I'm assuming this would need to be stored in a tuple - although not completely sure.
Say I have this group of 8 people
users =
["Steve", "Sally", "Barry", "Emma", "John", "Gustav", "Ankaran", "Gilly"]
I would like to split them up into a specific amount of groups.
For example, groups of 2, 3 or 4 people.
-- desired result
( ["Steve", "Sally", "Barry"]
, ["Emma", "John", "Gustav"]
, ["Ankaran", "Gilly"]
)
Part 2 of this question would be, How would you then iterate and render the results from a tuple of various lengths?
I was playing around with this example, using tuple-map
but it seems to only expect a tuple with 2 values.
import Html exposing (..)
import List
data = (
["Steve", "Sally", "Barry"]
, ["Emma", "John", "Gustav"]
, ["Ankaran", "Gilly"]
)
renderLI value =
li [] [ text value ]
renderUL list =
ul [] (List.map renderLI list)
main =
div [] (map renderUL data)
-- The following taken from zarvunk/tuple-map for examples sake
{-| Map over the tuple with two functions, one for each
element.
-}
mapEach : (a -> a') -> (b -> b') -> (a, b) -> (a', b')
mapEach f g (a, b) = (f a, g b)
{-| Apply the given function to both elements of the tuple.
-}
mapBoth : (a -> a') -> (a, a) -> (a', a')
mapBoth f = mapEach f f
{-| Synonym for `mapBoth`.
-}
map : (a -> a') -> (a, a) -> (a', a')
map = mapBoth
I'd like to be able to split a list up into multiple lists. I'm assuming this would need to be stored in a tuple - although not completely sure.
Tuples are fixed in the number of things they can carry. You can't have a function that accepts any size tuple.
It sounds like you'd like something more flexible, like a list of lists. You could define a split function like this:
import List exposing (..)
split : Int -> List a -> List (List a)
split i list =
case take i list of
[] -> []
listHead -> listHead :: split i (drop i list)
Now you've got a function that can split up any size list into a list containing lists of the requested size.
split 2 users == [["Steve","Sally"],["Barry","Emma"],["John","Gustav"],["Ankaran","Gilly"]]
split 3 users == [["Steve","Sally","Barry"],["Emma","John","Gustav"],["Ankaran","Gilly"]]
Your Html rendering now becomes simpler, since you only have to deal with lists of lists:
import Html exposing (..)
import List exposing (..)
split : Int -> List a -> List (List a)
split i list =
case take i list of
[] -> []
listHead -> listHead :: split i (drop i list)
users =
["Steve", "Sally", "Barry", "Emma", "John", "Gustav", "Ankaran", "Gilly"]
renderLI value =
li [] [ text value ]
renderUL list =
ul [] (List.map renderLI list)
main =
div [] (map renderUL <| split 3 users)
Updated answer for Elm 0.19
import List.Extra as E
E.groupsOf 3 (List.range 1 10)
--> [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]

Dynamically build list comprehension in Haskell

I am curious if it is possible to dynamically build a list comprehension in Haskell.
As an example, if I have the following:
all_pows (a,a') (b,b') = [ a^y * b^z | y <- take a' [0..], z <- take b' [0..] ]
I get what I am after
*Main> List.sort $ all_pows (2,3) (5,3)
[1,2,4,5,10,20,25,50,100]
However, what I'd really like is to have something like
all_pows [(Int,Int)] -> [Integer]
So that I can support N pairs of arguments without building N versions of all_pows. I'm still pretty new to Haskell so I may have overlooked something obvious. Is this even possible?
The magic of the list monad:
ghci> let powers (a, b) = [a ^ n | n <- [0 .. b-1]]
ghci> powers (2, 3)
[1,2,4]
ghci> map powers [(2, 3), (5, 3)]
[[1,2,4],[1,5,25]]
ghci> sequence it
[[1,1],[1,5],[1,25],[2,1],[2,5],[2,25],[4,1],[4,5],[4,25]]
ghci> mapM powers [(2, 3), (5, 3)]
[[1,1],[1,5],[1,25],[2,1],[2,5],[2,25],[4,1],[4,5],[4,25]]
ghci> map product it
[1,5,25,2,10,50,4,20,100]
ghci> let allPowers list = map product $ mapM powers list
ghci> allPowers [(2, 3), (5, 3)]
[1,5,25,2,10,50,4,20,100]
This probably deserves a bit more explanation.
You could have written your own
cartesianProduct :: [[a]] -> [[a]]
cartesianProduct [] = [[]]
cartesianProduct (list:lists)
= [ (x:xs) | x <- list, xs <- cartesianProduct lists ]
such that cartesianProduct [[1],[2,3],[4,5,6]] ⇒ [[1,2,4],[1,2,5],[1,2,6],[1,3,4],[1,3,5],[1,3,6]].
However, comprehensions and monads are intentionally similar. The standard Prelude has sequence :: Monad m => [m a] -> m [a], and when m is the list monad [], it actually does exactly what we wrote above.
As another shortcut, mapM :: Monad m => (a -> m b) -> [a] -> m [b] is simply a composition of sequence and map.
For each inner list of varying powers of each base, you want to multiply them to a single number. You could write this recursively
product list = product' 1 list
where product' accum [] = accum
product' accum (x:xs)
= let accum' = accum * x
in accum' `seq` product' accum' xs
or using a fold
import Data.List
product list = foldl' (*) 1 list
but actually, product :: Num a => [a] -> a is already defined! I love this language ☺☺☺