How to collect and map values of custom types of a record to a string - elm

How could I simplify the code of display more:
Here is my beginner code:
type Symbol = Cherry | Seven | Bar | Grapes
type alias Model =
{ one : Symbol
, two : Symbol
, three : Symbol
}
-- VIEW
display1 : Model -> String
display1 model =
case model.one of
Cherry ->
"Cherry"
Seven ->
"Seven"
Bar ->
"Bar"
Grapes ->
"Grapes"
display2 : Model -> String
display2 model =
case model.two of
Cherry ->
"Cherry"
Seven ->
"Seven"
Bar ->
"Bar"
Grapes ->
"Grapes"
display3 : Model -> String
display3 model =
case model.three of
Cherry ->
"Cherry"
Seven ->
"Seven"
Bar ->
"Bar"
Grapes ->
"Grapes"
display : Model -> String
display model =
display1(model) ++ " " ++ display2(model) ++ " " ++ display3(model)

You can pass Symbol type instead of the Model and have 1 function instead of 3:
type Symbol = Cherry | Seven | Bar | Grapes
type alias Model =
{ one : Symbol
, two : Symbol
, three : Symbol
}
-- VIEW
display1 : Symbol -> String
display1 symbol =
case symbol of
Cherry ->
"Cherry"
Seven ->
"Seven"
Bar ->
"Bar"
Grapes ->
"Grapes"
display : Model -> String
display model =
display1(model.one) ++ " " ++ display1(model.two) ++ " " ++ display1(model.three)

Related

KOTLIN - For loop argument is not support function - Looking for alternatives

The code below is for calculating exam results. 5 subject names and 5 points received from those subjects are recorded by the user in empty arrays created.
I have solved everything here. But I want to add "th" "st" "rd" "nd" after "cycle". Which is written "Please type lesson" and "Please type point"
For Example:
"Please type 1st point"
But with my code I can:
"Please type 1 point"
I tried to execute this process with the "When" condition, but I cannot because the loop argument "cycle" do not support the last() function
For example:
when (cycle.last()) {
1 -> "st"
2 -> "nd"
}
It will give me a result if worked 11st, 531st, 22nd, 232nd, etc. That's I want
fun main() {
var subject = Array<String>(5){""}
var point = Array<Int>(5){0}
for (cycle in 0 until subject.count()) {
println("Please type ${cycle+1} lesson")
var typeLesson = readLine()!!.toString()
subject[cycle] = typeLesson
println("Please type ${cycle+1} point")
var typePoint = readLine()!!.toInt()
point[cycle] = typePoint
}
var sum = 0
for (cycle in 0 until point.count()) {
println("${subject[cycle]} : ${point[cycle]}")
sum = sum + point[cycle]/point.count()
}
println("Average point: $sum")
}
You can divide the number by 10 and get the remainder using %. That is the last digit.
fun Int.withOrdinalSuffix(): String =
when (this % 10) {
1 -> "${this}st"
2 -> "${this}nd"
3 -> "${this}rd"
else -> "${this}th"
}
Usage:
println("Please type ${(cycle+1).withOrdinalSuffix()} lesson")
Note that in English, 11, 12, 13 have the suffix "th", so you might want to do:
fun Int.withOrdinalSuffix(): String =
if ((this % 100) in (11..13)) { // check last *two* digits first
"${this}th"
} else {
when (this % 10) {
1 -> "${this}st"
2 -> "${this}nd"
3 -> "${this}rd"
else -> "${this}th"
}
}
instead.

Access columns of a list by entering them as arguments of a function in elm

type alias Footballer =
{ name : String, age : Float, overall : Float, potential : Float }
type alias Point =
{ pointName : String, x : Float, y : Float }
pointName : Footballer -> Point
pointName x a b c=
Point x.a x.b x.c
I am trying to create points for a scatterplot and want to be able to provide the function with a Player and 3 columns I want to be able to provide variably.
I am struggling with elm, as I am trying to access fields of my List of Football players variably but I can not seem to find a way to do this without rewriting the function pointName for each Variation of Points I want to create.
Elm automatically generates polymorphic accessor functions for all the fields of the records used. (e.g. .age : { a | age : b } -> b) You can use these functions as arguments to pointName and apply them in the body of the function to extract the targeted field.
pointName :
r
-> (r -> String)
-> (r -> Float)
-> (r -> Float)
-> Point
pointName r a b c =
Point (a r) (b r) (c r)
player =
{ name = "Messi", age = 34, overall = 99, potential = 100 }
foo =
pointName player .name .age .potential
bar =
pointName player (.age >> String.fromFloat) .overall .potential

How can I create a function that only accepts a subset of constructors of a type?

Let's say I have a type like this:
data Foo = Bar String | Baz | Qux String
I want to have a function like this:
get : Foo -> String
get (Bar s) = s
get (Qux s) = s
As written, this compiles, but it's not total, as there are missing cases; in other words, get Baz is treated like a hole rather than as an expression that doesn't typecheck.
I want to replace that Foo in the type signature of get with something that specifies that the value must be either a Bar or a Qux. How can I express this subset of the Foo type?
You could also mix the two approaches (by Kim Stiebel and Anton Trunov) and construct a helper data type. The type OnlyBarAndQux can only be constructed with values of Bar and Qux. For idris it is then possible to automatically infer a proof if this is the case when invoking get:
module FooMe
data Foo = Bar String | Baz | Qux String
data OnlyBarAndQux: Foo -> Type where
BarEy: OnlyBarAndQux (Bar s)
QuxEx: OnlyBarAndQux (Qux s)
||| get a string from a Bar or Qux
total
get: (f: Foo) -> {auto prf : OnlyBarAndQux f} -> String
get (Bar s) {prf = BarEy} = s
get (Qux s) {prf = QuxEx} = s
-- Tests
test1: get $ Bar "hello" = "hello"
test1 = Refl
test2: get $ Qux "hello" = "hello"
test2 = Refl
-- does not compile
-- test3: get $ Baz = "hello"
I'd follow the approach taken in the std library for List head, for example. This is basically what Markus wrote plus using Dec for witnessing that a Foo being not Baz is decidable:
%default total
data Foo = Bar String | Baz | Qux String
data NotBaz : Foo -> Type where
IsBar: NotBaz(Bar z)
IsQux: NotBaz(Qux z)
Uninhabited (NotBaz Baz) where
uninhabited _ impossible
notBaz : (f : Foo) -> Dec (NotBaz f)
notBaz Baz = No absurd
notBaz (Bar s) = Yes IsBar
notBaz (Qux s) = Yes IsQux
get: (f : Foo) -> {auto ok : NotBaz f} -> String
get (Bar s) { ok = IsBar } = s
get (Qux s) { ok = IsQux } = s
s: String
s = get (Bar "bar")
Some comments about this:
Do not use just a predicate a -> Bool for working with a subset type of a; create a view like NotBaz above. See the Idris tutorial on views, this post, and this answer for context.
Use Dec whenever possible instead of equality. Intutitively, you will be able to use Dec for predicates on types for which you can explicitly decide the truth of the predicate: see notBaz above.
auto implicit arguments can help reducing the visual/cognitive clutter at usage site
There is more than one way to do this, but the easiest is probably to make Foo a type constructor that takes a parameter indicating whether it's a Foo with a String in it or not. In this example I have used a Bool as the parameter:
%default total
data Foo : Bool -> Type where
Bar : String -> Foo True -- a Foo constructed with Bar will have type Foo True
Baz : Foo False -- and a Foo constructed with Baz will have type Foo False
Qux : String -> Foo True
get : Foo True -> String
get (Bar s) = s
get (Qux s) = s
I'd go with Kim Stebel's answer (if changing Foo is an option, as observed by #Eduardo Pareja Tobes), but I'd like to show another way. You can use a subset type, which is the same thing as dependent pair:
total
get : (f ** Not (f = Baz)) -> String
get (f ** pf) with (f)
get (f ** _) | (Bar s) = s -- this is as before
get (f ** contra) | Baz = void $ contra Refl -- a contradictory case
get (f ** _) | (Qux s) = s -- this is as before
(f ** Not (f = Baz)) can be translated as "some f of type Foo, but not Baz".
To call get you need to provide a dependent pair of an element of type Foo and a proof that it is not equal to Baz, like so:
s : String
s = get (Bar "bar" ** \Refl impossible)

How to collapse a match on a discriminated union in F#

How does one take the results of a function that returns object, and cast it to a discriminated union in F#?
Problem scenario, I'm working with the javascript executor on a webdriver in selenium. The docs specify that the output should be an object of the certian types or list of types. (Ref https://www.w3.org/TR/webdriver/#executing-script)
I'd like to give the returning object some structure by casting it into a discriminated union so I can match on it later.
Casting directly doesn't work and union types aren't allowed to have constructors so I can't exactly drop it in there either. What's the proper way of going about this?
type JsResult =
| E of IWebElement
| I of Int64
| B of bool
| S of String
| LE of IWebElement list
| LI of Int64 list
| LB of bool list
| LS of String list
| N of Object
override self.ToString () =
match self with
| E e -> e.Text
| I i -> i.ToString()
| B b -> b.ToString()
| S s -> s
| LE le -> String.concat " " (le |> Seq.map(fun x-> x.Text))
| LI li -> String.concat " " (li |> Seq.map(fun x-> x.ToString()))
| LB lb -> String.concat " " (lb |> Seq.map(fun x-> x.ToString()))
| LS ls -> String.concat " " ls
| N _ -> String.Empty
let execute script : JsResult = (browser :?> IJavaScriptExecutor).ExecuteScript(script) :> JsResult
Maybe create a static factory method? Try this:
type JsResult =
// ...
with static member ofObject o =
match box o with
| :? IWebElement as e -> E e
| :? Int64 as i -> I i
| :? bool as b -> B b
| :? String as s -> S s
| :? (IWebElement list) as le -> LE le
| :? (Int64 list) as li -> LI li
| :? (bool list) as lb -> LB lb
| :? (String list) as ls -> LS ls
| :? Object as n -> N o
| _ -> failwith "No wrapper available for type"
let execute script : JsResult = (browser :?> IJavaScriptExecutor).ExecuteScript(script) |> JsResult.ofObject
(The boxing is only needed if any of the specified type is a value type like int, or bool).

OCaml - how to see module's interface?

Is it possible to see the interface of a loaded module in interactive OCaml? I have (unsuccessfully) tried searching for such a possibility, and online docs/sources are not what I am looking for.
The standard trick for this is to define a synonym for the module, which induces the toplevel to list the interface.
$ ocaml
OCaml version 4.00.1
# #load "str.cma";;
# module S = Str;;
module S :
sig
type regexp = Str.regexp
val regexp : string -> regexp
val regexp_case_fold : string -> regexp
val quote : string -> string
val regexp_string : string -> regexp
val regexp_string_case_fold : string -> regexp
val string_match : regexp -> string -> int -> bool
. . .
val first_chars : string -> int -> string
val last_chars : string -> int -> string
end
Update
(Note that this answer is from 2013. Recent revisions of OCaml provide a toplevel directive to show a module interface:
# #show_module Str;;
module Str :
sig
type regexp
val regexp : string -> regexp
. . .
val first_chars : string -> int -> string
val last_chars : string -> int -> string
end
So the semi-clever workaround is no longer required.
(There are many new directives. Type #help;; at toplevel to get a list.)
Both utop and ocaml interpreters added the #show directive since a moment. It does exactly what you want, as in the following example :
│ Welcome to utop version 1.19.3 (using OCaml version 4.04.0) │
└──────────────────────────────────────────────────────────────┘
Type #utop_help for help about using utop.
─( 15:12:33 )─< command 0 >──────────────────────────────────────{ counter: 0 }─
utop # #show List;;
module List :
sig
val length : 'a list -> int
val cons : 'a -> 'a list -> 'a list
val hd : 'a list -> 'a
...
val fast_sort : ('a -> 'a -> int) -> 'a list -> 'a list
val sort_uniq : ('a -> 'a -> int) -> 'a list -> 'a list
val merge : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
end
PS:i'm using 4.04 version but i know that it also works for 4.03.> and maybe before that too.
In OCaml toplevel version 4.04.0, the trick of defining a module's synonym works no more:
# module L = List;;
module L = List
#
but you can use the include directive:
# module L = struct include List end;;
module L :
sig
val length : 'a list -> int
val cons : 'a -> 'a list -> 'a list
val hd : 'a list -> 'a
val tl : 'a list -> 'a list
val nth : 'a list -> int -> 'a
val rev : 'a list -> 'a list
...
val sort_uniq : ('a -> 'a -> int) -> 'a list -> 'a list
val merge : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
end
#