Elm main function type annotation - elm

What is the meaning of this Elm example's main function type annotation?
main : Html msg
main =
div [] [ text "1" ]
What is Html and msg?

First of all, that one is not a function, because it doesn't take any parameter.
However, type annotation is saying that the main is of type Html with a not yet known variant msg.
Html is the type, like Int or String, and msg is the type variant.
Some types can have variants, take List a as an example.
List a means that you are declaring a List where the type variant is irrelevant or not yet known. For instance, the type annotation for List.length method is:
length : List a -> Int
When you'll use this method, you'll certainly have a type instead of a, like String or Int or whatever, by the behaviour of length doesn't change.
Don't be confused then by the msg addition to Html. It has the same meaning. In Elm you render html code that may dispatch some messages, and you usually define them as a union type like:
type Msg
= ClickedSave
| EnteredText String
So, your main declaration can remain Html msg, or Html a until you dispatch a message.
If you, for instance, add an onClick handler to your div like:
main =
div [ onClick ClickedSave ] [ text "1" ]
the type annotation becomes (whether you annotate it or not) Html Msg, because now the message you are dispatching is of type Msg.
Hope it's clear, and sorry for my english, it's not my native language.

Related

Dynamically created class with invocant constraint

Official docs says that class can be built dynamically like so:
constant A := Metamodel::ClassHOW.new_type( name => 'A' );
A.^add_method('x', my method x(A:D:) { say 42 });
A.^compose;
A.new.x(); # x will be only called on instances
But what if I am building a class and don't assign it to a constant but rather store it in a var (for instance when I need to create a bunch of classes in loop) like so:
my $x = Metamodel::ClassHOW.new_type( name => 'some custom string' );
$x.^add_method('x', my method ($y:) { say $y });
$x.^compose;
But in this case I can call method x both on class ($x.x) and on instance ($x.new.x) though I want it to only be called on instances.
I tried to define method like so:
$x.^add_method('x', my method ($y:D:) { say $y });
but that produces an error:
Invalid typename 'D' in parameter declaration.
Of course I can check defindness of the value inside the method but I want some compile-time guarantees (I want to believe that type checking is done in compile time).
I tried to play with signatures and parameters but couldn't find a way to create an invocant parameter but what is more important I am not sure how to assign signature which I have in a variable to some method.
Change:
my $x = ...
to:
my constant x = my $ = ...
In full:
my constant x = my $ = Metamodel::ClassHOW.new_type( name => 'some custom string' );
x.^add_method('x', my method (x:D $y:) { say $y });
x.^compose;
x = Metamodel::ClassHOW.new_type( name => 'another custom string' );
...
I want some compile-time guarantees (I want to believe that type checking is done in compile time).
By making the constant's RHS be a variable declaration, you blend static compile-time aspects with dynamic run-time ones.
(BTW, the my before constant is just me being pedantic. A plain constant like you've used is equivalent to our constant which is less strict than my constant.)
I note the error message for a non-instance is different:
Type check failed in binding to parameter '$y';
expected type some custom string cannot be itself
At a guess that's because the usual message comes from Mu or Any and your class isn't inheriting from either of them.
I am not sure how to assign signature which I have in a variable to some method.
I'll leave that part unanswered.
The best way I can think of to produce a method with types substituted into a signature with Raku today is to use a parametric role to help out, like this:
my role Helper[::T] {
method foo(T $inv:) {}
}
my &meth = Helper.^parameterize(Int).^pun.^lookup("foo");
say &meth.signature;
Which outputs (Int $inv: *%_). Substitute Int with the type you are building.

Parsing of YAML file with Jackson fails if value starts with special character

I am trying to parse the following YAML-content:
template:
amplitude: 5
noise: +-0.01
This fails with this exception:
com.fasterxml.jackson.databind.JsonMappingException: empty String (through reference chain: ... ->my.package.Template["noise"])
The class Template contains a property noise of type FlexValue. I made a custom JsonDeserializer that is responsible to parse the values for properties of this type. The notation allows somewhat fancy expressions, hence the name FlexValue for the type. The value in this example, "+-0.01", is a valid input for the deserializer. However, it seems like the deserializer isn't even called. The exception seems to be thrown before that.
Here is the relevant class definition of my custom deserializer:
class FlexValueParser : JsonDeserializer<FlexValue>() {
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): FlexValue {
//...
}
}
The custom deserializer is registered as follows:
#JsonDeserialize(using = FlexValueParser::class)
class FlexValue {
// ...
}
This setup seems to work fine. It does on other types as well, which are parsed differently.
If I prepend a "0" before "+-", which is also a valid input, it works:
template:
amplitude: 5
noise: 0+-0.01
Is "+-" a special cahracter in YAML that causes Jackson to fail parsing it, because it tries to do something else than I expect? I expect it to treat the input "+-0.01" as a String because it doesn't represent a valid number input.
The same problem occurs, when I use noise: ~0.01, which is also a valid input for my deserializer. The same exception is thrown on this and can be avoided by prepending a "0" before the curly "~".
Can someone give me a hint on this?
Found the source of the problem, which had nothing to do with Jackson or YAML. Closing this question therefore.

Interpreting elm function declaration syntax

I am not able grasp the following function declaration & definition syntax of elm language.
keyDown: (Int -> Msg) -> Attribute msg
keyDown event =
on "keydown" (Json.map event keyCode)
What does the first line means?
keyDown: (Int -> Msg) -> Attribute msg. Does it means, that the keyDown function takes, Int & Msg type params & returns of type Attribute?
What exactly happens in the function definition part?
How the parameters to the function are defined?
TL;DR
keyDown function accepts another function as an argument and returns an attribute, which Elm's renderer uses to attach an event listener.
If you define a type
type Msg
= KeyDown Int
The KeyDown acts as a constructor function for values of type Msg, so we can say that the implicit type of it is KeyDown: Int -> Msg, which is what you want when you want to retrieve a key code from a DOM Event.
Explanation
First of all, I must say that the proper implementation should look like this:
keyDown : (Int -> msg) -> Attribute msg
keyDown tagger =
on "keydown" (Json.Decode.map tagger keyCode)
It is important to have msg type variable in the signature, so it's possible to use this event listener in different parts of the application, where Html emits different types of msg
To understand what is happening here, let's look closer at Html.Events.on
on : String -> Decoder msg -> Attribute msg
Every DOM event is represented as a JavaScript object with certain fields. To retrieve the data from JavaScript, Elm needs to pass it through a Decoder to ensure type safety in runtime, just like with HTTP requests.
The decoder in on is expected to produce the same type of message, as the attribute itself.
By default, keyCode decoder decodes an Int value, but what we want is to emit some message.
That's where Json.Decode.map helps us to get the Int and apply some tagger function, which produces a message.
Decoder
The entire (Json.map event keyCode) part is essentially a Decoder msg, which is applied to the event object to extract the key code and "tag" it with a message.

Handling input data undefined error

Inspired by this question, I want to ask about how to handle input data type error in Rust. For example, the following function require input data type to be enum Animal. How about the user actually give an input with not-defined data type or even a empty one.
Should I add a None => None or _ => None in the match?
use std::fmt;
use std::io::prelude::*;
pub enum Animal {
Cat(String),
Dog,
}
impl fmt::Display for Animal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Animal::Cat(ref c) => f.write_str("c"),
Animal::Dog => f.write_str("d"),
}
}
}
fn main() {
let p: Animal = Animal::Cat("whiskers".to_owned()); // yes, work!
let p: Animal = Animal::BadCat("whiskers".to_owned()); // Badcat not defined,??
}
Compiler error:
error: no associated item named `BadCat` found for type `Animal` in the current scope
--> <anon>:20:25
|
20 | let p: Animal = Animal::BadCat("whiskers".to_owned()); // Badcat not defined,??
| ^^^^^^^^^^^^^^
Rust is a strongly1, statically typed, compile-time type checked language.
This means that unlike, say, Python, it is impossible for a user to pass an invalid type to your function (unless they're passing data that has been invalidly coerced via unsafe, but you can't reasonably detect this. See my post about incorrect transmutations to bool). You do not need to worry about this.
In the more general case, the only time you need to worry about type variant checking in Rust is when receiving data from outside Rust, e.g. through a configuration or data file, or else an FFI function. In these cases, it's customary to return a Result<Animal,ErrorMessage> of some sort to indicate bad data. However, in some cases, especially in FFI, if you receive data that's particularly malformed it may be acceptable to panic!.
This type of checking usually does not involve match statements on an enum, but rather more fundamental checks such as assertions about string or integer comparisons being one of a set of known values that you're trying to reinterpret to a higher level enum type.
1 There's some inconsistency and disagreement on what "strongly typed" actually means, in this case I'm using it to mean "few if any implicit type coercions".

What is the purpose of Unit-returning in functions

From the Kotlin documentation:
If a function does not return any useful value, its return type is Unit. Unit is a type with only one value — Unit.VALUE. This value does not have to be returned explicitly:
fun printHello(name : String?) : Unit {
if (name != null)
print("Hello, $name!")
else
print("Hi there!")
// We don't need to write 'return Unit.VALUE' or 'return', although we could
}
What is the purpose of Unit-returning in functions? Why is VALUE there? What is this VALUE?
The purpose is the same as C's or Java's void. Only Unit is a proper type, so it can be passed as a generic argument etc.
Why we don't call it "Void": because the word "void" means "nothing", and there's another type, Nothing, that means just "no value at all", i.e. the computation did not complete normally (looped forever or threw an exception). We could not afford the clash of meanings.
Why Unit has a value (i.e. is not the same as Nothing): because generic code can work smoothly then. If you pass Unit for a generic parameter T, the code written for any T will expect an object, and there must be an object, the sole value of Unit.
How to access that value of Unit: since it's a singleton object, just say Unit
The main reason why Unit exists is because of Generic reasons.
Let's use the example from the Kotlin docs.
class Box<T>(t: T) {
var value = t
}
We can have
var box = Box(Unit)
This is why Unit returns a value so the Kotlin can infer it from the type passed into class initialization. Of course, you could also explicitly write it like this,
var box = Box<Unit>(Unit)
but all the same, it must have a return value.
Now, the void keyword in Java in Kotlin is Nothing. Nothing is the last but one type in the type hierarchy in Kotlin with the last one being Nothing? (Nullable Nothing). This does not return any value at all. Because it doesn't return any value at all, we can't pass it as a type in the above code.
var box = Box(Nothing) //This will return an Error
UNIT actually contains valuable information, it basically just means "DONE". It just returns the information to the caller, that the method has been finished. This is a real piece of information so it can be seen as the return value of a method.