How to view custom type in elm? - elm

here is data model , the goal is easy, just to view the type Gift in the HTML and user can use a dropdown list to update field type_ of Gift. But the question is how to build dropdown list from a custom type ?
type Fruit
= Apple
| Banana
| Orange
type alias Gift =
{ quantity : int
type_ : Fruit
}
I tried to add a update/view operation on view
how to convert the type Fruit to String ? There are two possible workarounds:
Building a dict, which mays Fruit to String
{Apple:"Apple",Banana,"Banana"}
I don't think this will work since key in Dict needs to be Comparable,but how to implement ordering in custom type ? there was an issue but there seems no solution yet (https://github.com/elm/compiler/issues/774)
Using Enum/makeEnum module
this will bring more code and easily can break.
fruitTypeEnum = Enum.makeEnum [Apple, Banana, Orange ]
-- in view
(List.map (\x -> Enum.toString fruitTypeEnum x) [Apple,Banana,Orange])
this has to maintain apple,banana,orange list in three places ( including the declaration )
Thank you for your time reading this .Appreciate any help:)

There is no built in way in Elm to get a list of all of the variants of a custom type (Elm generally shies away from "magic" metaprogramming in favor of explicitness). As glennsl answered, using a case expression is a very clean and straightforward way to implement a toString function for a custom type.
The list of all variants of that type must be keep separately from the type definition itself, but you should create one list, maybe named allFruit in this case, that you can use anywhere you want to list them all out. Tests can help you ensure you don't miss anything when asking a new variant.
One more advanced technique is using code generation to create a list from the source code automatically.

I'll only answer the first question here (see my comment). No Dict needed, it's a simple function:
fruitToString : Fruit -> String
fruitToString fruit =
case fruit of
Apple -> "Apple"
Banana -> "Banana"
Orange -> "Orange"

To answer the other question about using other types as keys in Dict, there is the possibility to use assoc-list instead: https://package.elm-lang.org/packages/pzp1997/assoc-list/latest/
import AssocList as Dict exposing (Dict)
type Fruit
= Apple
| Banana
| Orange
fruitStrings : Dict Fruit String
fruitStrings =
Dict.fromList
[ ( Apple, "Apple" )
, ( Banana, "Banana" )
, ( Orange, "Orange" )
]
fruitToString : Fruit -> String
fruitToString fruit =
Dict.get fruit fruitStrings |> Maybe.withDefault "Not a fruit"
As you can see, with a Dict you need to handle a case that could never happen. The case construction is therefore preferable here. But now you know how to create a dictionary with custom types as keys.

Related

Kotlin: Use specific values as a type

I want to model the result of two six sided dice in Kotlin.
In TypeScript you can do something like this:
type SixSidedDie = 1 | 2 | 3 | 4 | 5 | 6
I would like to do something similar in Kotlin with
typealias SixSidedDie = 1 | 2 | 3 | 4 | 5 | 6
Which of course doesn't work because the compiler expects a type.
Is there any way in Kotlin to use constant values as a type?
Is there any way in Kotlin to use constant values as a type?
Not at the moment, and I haven't seen it discussed so far. This is because, without union types, I don't think those are really useful (you could use objects for that purpose).
There is an issue tracking the possible addition of denotable union types to the language: https://youtrack.jetbrains.com/issue/KT-13108/Denotable-union-and-intersection-types
Now about your precise use case, there is also nothing currently available in Kotlin to represent subsets of numbers as a type. The closest you can get, as mentioned in the comment, is an enum:
enum class Dice6Result {
ONE, TWO, THREE, FOUR, FIVE, SIX
}
Or with an associated Int value if you need it:
enum class Dice6Result(val value: Int) {
ONE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6)
}
Note, that union types still would not solve the Int subset problem unless constant values could be used as types (as you were asking for).
Another option for you could be to use a value class to wrap the integer value, and check in an init block at construction time that the value is within the bounds. However, this becomes a runtime check, which might be less interesting than an enum.

Multiple user inputs and autocomplete in Plotly Dash

I'm searching for a way to have suggestions "persisting" in a input widget so that user can use suggestions to create more complex strings.
E.g. if I were to create this list of possible input values:
html.Datalist(id='browser', children=[
html.Option(value="apple"),
html.Option(value="pear"),
html.Option(value="banana")
]),
(and say parameter multiple is set to True (see Dash input widget documentation))
user wouldn't be able to use the suggestions/autocomplete to create more complex strings, for instance:
apple pear and tomatoe
where the fruits names would be suggested.
I spent a great deal of time searching online but couldn't find out anythin hint on this. Any suggestion/direction much welcome.

Kotlin functional programming keep reference of previous object in List

I have a list of Person objects which are related to each other with spouse relation in the order of which they appear in the list.
enum class Gender {
MAN, WOMAN
}
data class Person(val name: String, val age: Int, val gender: Gender)
In the list, each Person with Gender MAN is the spouse of the following Person with WOMAN Gender (and vice versa) and each entry in the list is followed by alternating genders with MAN gender be the first.
The list should ideally be like [MAN, WOMAN, MAN, WOMAN, MAN, WOMAN] (obviously it will be a list of Person objects for simplicity I am putting a list of Gender here) but it could also be like [WOMAN, MAN, WOMAN, MAN, WOMAN, MAN]. In the latter case, the first appearing WOMAN is the spouse of the last appearing MAN.
How this second case could be handled in kotlin by using functional programming.
My current approach involves checking if the first Person has a gender women then i remove the first and last objects in the list and then add them in the end but this is not fully a functional programming solution.
Anyone can guide me about that?
Thanks
What do you mean by fully functional approach?
Similar to what you mentioned, you can fix the order by a simple statement like this:
val correctList = if(list.first().gender == MAN) list else list.drop(1) + list.first()
If you want a more general approach, you can do something like this:
// separate the people into a list of gender=MAN and a list of everyone else
// the result is a Pair, so I'm destructuring that into two variables
val (men, women) = people.partition { it.gender == MAN }
// use zip to take a person from each list and combine them into a list of pairs
men.zip(women)
// use flatMap to turn each pair into a list of two people
// just using map would create a list of lists, flatMap flattens that into
// a single list of people, alternating gender=MAN, gender=WOMAN
.flatMap { it.toList() }
This way it doesn't matter how your original list is ordered, it can start with any element and you can have the different types completely mixed up - BABBAABA will still come out as ABABABAB. So it's a general way to combine mixed data streams - partition separates them into groups, and zip lets you take an element from each group and do something with them.
Here I'm just letting zip create Pairs, and then flatMap turns those back into an ordered list (if that's what you want). You could also do a forEach on each pair instead (say if you wanted to set a value on each Person to link them to each other), or zip can take a transform function too.
Also zip terminates when one of the lists runs out (e.g for AAA and BB you'll get two pairs) so this works for generating complete pairs of elements - if you also needed to handle elements without a "partner" you'd need to do a bit more work

How do you write Lua code for an input request and then outputs a result from a lookup

I would like some assistance on writing some Lua code in which if a user inputs a color for a car the code will be able to search a lookup table to see if that color is included in the lookup table as a keyword and will be able to output a score which defines the result for example 1 = accept, 2 = decline deepening on what color car they have typed at the beginning.
Thank you
This is a rather trivial program in lua. because lua allows for simple creation of associative arrays(a.k.a. hash tables) you can quickly make a lookup table.
local carColors = {
purple = "1"
}
From there you index the table with your user input and return your 1 or 2
local userInput = io.read():lower() --Make sure to set the user input to all lowercase.
print(carColors[userInput] or "2") -- if nil return 2
I used print rather than io.output.
the or here lets the code handle when the user gives a bad color name when carColors[userInput] is nil the 2 will be printed.

How would you structure a spreadsheet app in elm?

I've been looking at elm and I really enjoy learning the language. I've been thinking about doing a spreadsheet application, but i can't wrap my head how it would be structured.
Let's say we have three cells; A, B and C.
If I enter 4 in cell A and =A in cell B how would i get cell B to always equal cell A? If i then enter =A+B in cell C, can that be evaluated to 8, and also be updated when A or B changes?
Not sure how to lever Signals for such dynamic behavior..
Regards Oskar
First you need to decide how to represent your spreadsheet grid. If you come from a C background, you may want to use a 2D array, but I've found that a dictionary actually works better in Elm. So you can define type alias Grid a = Dict (Int, Int) a.
As for the a, what each cell holds... this is an opportunity to define a domain-specific language. So something like
type Expr = Lit Float | Ref (Int, Int) | Op2 (Float -> Float -> Float) Expr Expr
This means an expression is either a literal float, a reference to another cell location, or an operator. An operator can be any function on two floats, and two other expressions which get recursively evaluated. Depending on what you're going for, you can instead define specific tags for each operation, like Plus Expr Expr | Times Expr Expr, or you can add extra opN tags for operations of different arity (like negate).
So then you might define type alias Spreadsheet = Grid Expr, and if you want to alias (Int, Int) to something, that might help too. I'm also assuming you only want floats in your spreadsheet.
Now you need functions to convert strings to expressions and back. The traditional names for these functions are parse and eval.
parse : String -> Maybe Expr -- Result can also work
eval : Spreadsheet -> Grid Float
evalOne : Expr -> Spreadsheet -> Maybe Float
Parse will be a little tricky; the String module is your friend. Eval will involve chasing references through the spreadsheet and filling in the results, recursively. At first you'll want to ignore the possibility of catching infinite loops. Also, this is just a sketch, if you find that different type signatures work better, use them.
As for the view, I'd start with read-only, so you can verify hard-coded spreadsheets are evaluated properly. Then you can worry about editing, with the idea being that you just rerun the parser and evaluator and get a new spreadsheet to render. It should work because a spreadsheet has no state other than the contents of each cell. (Minimizing the recomputed work is one of many different ways you can extend this.) If you're using elm-html, table elements ought to be fine.
Hope this sets you off in the right direction. This is an ambitious project and I'd love to see it when you're done (post it to the mailing list). Good luck!