Variables in Julia change their type while being constructed - constructor

I am brand new in Julia programming, and am facing a baffling situation, which I simply can't understand. So, this is what I want to do: I have two structs: Shoe and Person, where Person contains a Shoe
This is how the code looks:
struct Shoe
size :: Int64
brand :: String
end
struct Person
age :: Int64
shoe :: Shoe
function Person(a::Int64, s::Shoe)
age = a
shoe = s
end
function Person()
age = 33
shoe = Shoe(17,"Nike")
end
end
ian = Person(17, Shoe(32,"Puma"))
tom = Person()
println(typeof(ian))
println(typeof(tom))
To my utter surprise, ian and tom, which I try to define as persons, turn out to be shoes. Any idea what am I doing wrong?

function Person, being a constructor for the struct Person, should return an instance of struct Person, but because its last line is shoe = Shoe(17,"Nike") (and because assignment is an expression that evaluates to whatever shoe becomes), it ends up returning that Shoe.
Constructors should call the built-in new constructor:
struct Person
age :: Int64
shoe :: Shoe
# This function is redundant since
# it does exactly the same thing as the `new` constructor
function Person(a::Int64, s::Shoe)
age = a
shoe = s
new(age, shoe)
end
function Person()
age = 33
shoe = Shoe(17,"Nike")
new(age, shoe)
end
end
AFAIK, you don't need to use constructors unless they're doing input validation. You do need a constructor to ensure that it's impossible to construct a Person with negative age, for example, because Int64 can be negative. (You could ensure that age >= 0 by using UInt64, too. But then you'd have to write 17 in hexadecimal (0x11) all the time, which is kind of annoying)
I'd write it like this:
struct Person
age :: Int64
shoe :: Shoe
function Person(age::Int64, shoe::Shoe)
#assert age >= 0
new(age, shoe)
end
end
# Put other constructors outside
Person() = Person(33, Shoe(17, "Nike"))
Example:
julia> Person(-1, Shoe(0, "Hello"))
ERROR: AssertionError: age >= 0
Stacktrace:
[1] Person(age::Int64, shoe::Shoe)
# Main ./REPL[3]:6
[2] top-level scope
# REPL[5]:1
julia> Person()
Person(33, Shoe(17, "Nike"))

Related

Dont understand whats on in this haskell code

I have some haskell code Im trying to work my way thourgh but I dont have understand what is going in it.
type Bag a = a -> Int
emptyB :: Bag a
emptyB = \e -> 0
countB :: Eq a => Bag a -> a -> Int
countB b e = b e
I understand that the Bag type is a function that takes in a generic object and returns a Int and countB is basically a wrapper for Bag that gets the number of generic objects in that Bag. But I dont really understand anything past that. How do I modify whats in the bag? Or the bag itself? From what I figure adding to the bag would be something like
addB :: Eq a => Bag a -> a -> Bag a
addB bag num = bag (num+bag)
But this returns a int, when the add function requires a bag be returned. Can anyone explain to me how this works?
Terms and Discussion
type Bag a = a -> Int
Here Bag is not an object. It is just a type - an alias for a -> Int. If you have a value of type a it will compute and return a value of type Int. That's it. There is no Bag, no structure to which you can add things. It would be better to not even call this a Bag.
emptyB :: Bag a
emptyB = \e -> 0
A function from any type to the constant number zero.
countB :: Eq a => Bag a -> a -> Int
countB b e = b e
In short, this is just function application. Apply the function named b to the input e.
Rewriting for fun and learning
I appreciate that you can use functions to imitate structures - it's a common programming language class assignment. You can take a Bag a and another Bag a then union them, such as returning a new countB by adding the counts of the two individual bags - cool.
... but this seems too much. Before moving on with your assignment (did I guess that right?) you should probably become slightly more comfortable with the basics.
It might be easier if you rewrite the functions without the type alias:
emptyB :: a -> Int
emptyB = \e -> 0
-- or: emptyB e = 0
-- or: emptyB _ = 0
-- or: emptyB = const 0
Bag or no bag, it's just a function.
countB :: Eq a => (a -> Int) -> a -> Int
countB b e = b e
A function that takes an a and produces an Int can... be given a value (the variable e is of type a) and produce an Int.

Is it possible to write a recursive grouping function like this in f#

Lets say you had a requirement to group a sequence into a sequence of tuples. Each tuple is a key*seq. So in a sense, the result is a sequence of sequences.
All pretty standard so far.
What if you wanted to further group each sub sequence by some other key? It would be easy enough to map another groupby function onto each element of your sequence of sequences. You would then have a sequence of sequences of sequences.
Starting to get slightly hairy.
What if you wanted to group it even further?
Would it be possible to write a function that can take in a key generating function and an arbitrary sequence, and recursively unwraps the layers and then adds another layer of grouping using the keyFunction?
I suspect the answer is no, because the recursive function would not have a well defined type.
My attempt at this, to further illustrate the idea:
let rec recursiveGrouper keyFunction aSeq =
let first = Seq.head aSeq
match first with
| ((a:'a), _) -> Seq.map (fun (b,(c:seq<'c>)) -> (b, recursiveGrouper keyFunction c)) aSeq
| _ -> Seq.groupBy keyFunction aSeq
EDIT:
Lets add an example of how this might work, it it were possible
type FruitRecord = {Fruit:string; Number:int; SourceFarm:string; Grade:float}
let key1 fr =
fr.Fruit
let key2 fr =
fr.SourceFarm
let key3 fr =
match fr.Grade with
|f when f > 5.0 -> "Very Good"
|f when f > 2.5 -> "Not bad"
|_ -> "Garbage"
Lets say we have a whole bunch of fruit records in a sequence. We want to group them by type of fruit.
One way would be to say
let group1 = fruitRecs |> Seq.groupBy key1
Using our recursive function, this would be
let group1 = recursiveGrouper key1 fruitRecs
Next, lets say we want to group each of the items in the groups of group1 by source farm.
We could say
let group2 =
group1
|> Seq.map (fun (f, s) -> (f, Seq.groupBy key2 s))
Using our recursive function it would be
let group2 = recursiveGrouper key2 group1
And we could go further and group by Grade by saying
let group3 = recursiveGrouper key3 group2
Actually there are some ways to make that recursive function work, using static constraints. Here's a small example:
// If using F# lower than 4.0, use this definition of groupBy
module List =
let groupBy a b = Seq.groupBy a (List.toSeq b) |> Seq.map (fun (a, b) -> a, Seq.toList b) |> Seq.toList
type A = class end // Dummy type
type B = class end // Dummy type
type C =
inherit B
static member ($) (_:C, _:A ) = fun keyFunction -> () // Dummy overload
static member ($) (_:C, _:B ) = fun keyFunction -> () // Dummy overload
static member ($) (_:B, aSeq) = fun keyFunction -> List.groupBy keyFunction aSeq // Ground case overload
static member inline ($) (_:C, aSeq) = fun keyFunction -> List.map (fun (b, c) -> b, (Unchecked.defaultof<C> $ c) keyFunction) aSeq
let inline recursiveGrouper keyFunction aSeq = (Unchecked.defaultof<C> $ aSeq) keyFunction
// Test code
type FruitRecord = {Fruit:string; Number:int; SourceFarm:string; Grade:float}
let key1 fr = fr.Fruit
let key2 fr = fr.SourceFarm
let key3 fr =
match fr.Grade with
|f when f > 5.0 -> "Very Good"
|f when f > 2.5 -> "Not bad"
|_ -> "Garbage"
let fruitRecs = [
{Fruit = "apple" ; Number = 8; SourceFarm = "F"; Grade = 5.5}
{Fruit = "apple" ; Number = 5; SourceFarm = "F"; Grade = 4.5}
{Fruit = "orange"; Number = 8; SourceFarm = "F"; Grade = 5.5}
]
let group1 = recursiveGrouper key1 fruitRecs
let group2 = recursiveGrouper key2 group1
let group3 = recursiveGrouper key3 group2
I don't think you could write it as a recursive function with the sort of constraints you put on yourself - that is:
A tuple 'key * seq<'value> representing the grouping,
A heterogeneous key function (or a collection thereof) - this is what I understand by "group each sub sequence by some other key".
You could make some leeway if you would represent the grouping as an actual tree type (rather than an ad-hoc tree built from tuples) - that way you'd have a well-defined recursive result type to go with your recursive function.
If at that point you would be able to also compromise on the key function to make it homogeneous (worst case - producing a hashcode), you should be able to express what you want within the type system.
You certainly could have a non-recursive grouping function that takes a grouped sequence and puts another level of grouping on top of it - like the one below:
module Seq =
let andGroupBy (projection: 't -> 'newKey) (source: seq<'oldKey * seq<'t>>) =
seq {
for key, sub in source do
let grouped = Seq.groupBy projection sub
for nkey, sub in grouped do
yield (key, nkey), sub
}
Using your FruitRecord example:
values
|> Seq.groupBy key1
|> Seq.andGroupBy key2
|> Seq.andGroupBy key3

OCaml : Raise an error inside a match with structure

In OCaml, I have a list of strings that contains names of towns (Something like "1-New York; 2-London; 3-Paris"). I need to ask the user to type a number (if they want London they have to type 2).
I want to raise an exception message saying that the town is not valid, if the person types for example "4", in the example.
I tried this, but it doesn't work :
let chosenTown = match int_of_string (input_line stdin) with
| x > (length listOfTowns) -> raise (Err "Not a valid town")
What's the good way to code "if the chosen number is bigger than the length of the list then raise the error" ??
Pattern can't contain arbitrary expressions. It can be a constant, a constructor name, record field inside curly braces, list, array, etc.
But patterns can be guarded, e.g.
match int_of_string (input_line stding) with
| x when x >= length listOfTowns ->
invalid_arg "the number is too large"
| x -> List.nth listOfTowns x
To complete the answer, patter matching relies on unification and does not expect assertion (it is not the equivalent of a switch in C or so).
The idea is that you provide different "shapes" (patterns) that your term (the thing you match on) could have.
For a list for instance:
match l with
| e :: e' :: r -> (*...*)
| e :: r -> (*...*)
| [] -> (*...*)
It also had a binding effect, if you pass on, say, [1] (a very small list indeed), it won't match e :: e' :: r, but will match e :: r and then e = 1 and r = [].
As ivg said, you can add conditions, as booleans this time, thanks to the keyword when.
However, when manipulating lists like this, I would go for a recursive function:
let rec find_town n l =
match l with
| t :: _ when n = 1 -> t
| _ :: r -> find_town (n-1) r
| [] -> raise (Err "Not a valid town")
This is basically writing again List.nth but changing the exception that it raises.

OCaml function with variable number of arguments

I'm exploring "advanced" uses of OCaml functions and I'm wondering how I can write a function with variable number of arguments.
For example, a function like:
let sum x1,x2,x3,.....,xn = x1+x2,+x3....+xn
With a bit of type hackery, sure:
let sum f = f 0
let arg x acc g = g (acc + x)
let z a = a
And the (ab)usage:
# sum z;;
- : int = 0
# sum (arg 1) z;;
- : int = 1
# sum (arg 1) (arg 2) (arg 3) z;;
- : int = 6
Neat, huh? But don't use this - it's a hack.
For an explanation, see this page (in terms of SML, but the idea is the same).
OCaml is strongly typed, and many techniques used in other (untyped) languages are inapplicable. In my opinion (after 50 years of programming) this is a very good thing, not a problem.
The clearest way to handle a variable number of arguments of the same type is to pass a list:
# let sum l = List.fold_left (+) 0 l;;
val sum : int list -> int = <fun>
# sum [1;2;3;4;5;6];;
- : int = 21

Proving lemma with implication based on functions

I want to prove the lemma below. I am trying to to use tactic 'destruct', but I
can't prove it. Please any body guide me how can I prove such lemmas. I can prove it for EmptyString, but not for variables s1 and s2. Thanks
Inductive nat : Set :=
| O : nat
| S : nat -> nat.
Inductive string : Set :=
| EmptyString : string
| String : ascii -> string -> string.
Fixpoint CompStrings (sa : string) (sb : string) {struct sb}: bool :=
match sa with
| EmptyString => match sb with
| EmptyString => true
| String b sb'=> false
end
| String a sa' => match sb with
| EmptyString => false
| String b sb'=> CompStrings sa' sb'
end
end.
Lemma Eq_lenght : forall (s1 s2 : string),
(CompStrings s1 s2) = true -> (Eq_nat (length s1) (length s2)) = true.
First off, let me argue about style. You could have written your function CompStrings as this:
Fixpoint CompStrings' (sa : string) (sb : string) {struct sb}: bool :=
match sa, sb with
| EmptyString, EmptyString => true
| EmptyString, _
| _, EmptyString => false
| String a sa', String b sb'=> CompStrings sa' sb'
end.
I find it easier to read. Here is a proof it's the same as yours, in case you're suspicious:
Theorem CompStrings'ok: forall sa sb, CompStrings sa sb = CompStrings' sa sb.
Proof.
intros. destruct sa, sb; simpl; reflexivity.
Qed.
Now, this will be a two-fold answer. First I'm just going to hint you at the direction for the proof. Then, I'll give you a full proof that I encourage you not to read before you've tried it yourself.
First off, I assumed this definition of length since you did not provide it:
Fixpoint length (s: string): nat :=
match s with
| EmptyString => O
| String _ rest => S (length rest)
end.
And since I did not have Eq_nat either, I proceeded to prove that the lengths are propositionally equal. It should be fairly trivial to adapt to Eq_nat.
Lemma Eq_length' : forall (s1 s2 : string),
CompStrings s1 s2 = true ->
length s1 = length s2.
Proof.
induction s1.
(* TODO *)
Admitted.
So here is the start! You want to prove a property about the inductive data type string. The thing is, you will want to proceed by case analysis, but if you just do it with destructs, it'll never end. This is why we proceed by induction. That is, you will need to prove that if s1 is the EmptyString, then the property holds, and that if the property holds for a substring, then it holds for the string with one character added. The two cases are fairly simple, in each case you can proceed by case analysis on s2 (that is, using destruct).
Note that I did not do intros s1 s2 C. before doing induction s1.. This is fairly important for one reason: if you do it (try!), your induction hypothesis will be too constrained as it will talk about one particular s2, rather than being quantified by it. This can be tricky when you start doing proofs by induction. So, be sure to try to continue this proof:
Lemma Eq_length'_will_fail : forall (s1 s2 : string),
CompStrings s1 s2 = true ->
length s1 = length s2.
Proof.
intros s1 s2 C. induction s1.
(* TODO *)
Admitted.
eventually, you'll find that your induction hypothesis can't be applied to your goal, because it's speaking about a particular s2.
I hope you've tried these two exercises.
Now if you're stuck, here is one way to prove the first goal.
Don't cheat! :)
Lemma Eq_length' : forall (s1 s2 : string),
CompStrings s1 s2 = true ->
length s1 = length s2.
Proof.
induction s1.
intros s2 C. destruct s2. reflexivity. inversion C.
intros s2 C. destruct s2. inversion C. simpl in *. f_equal.
exact (IHs1 _ C).
Qed.
To put that in intelligible terms:
let's prove the property forall s2, CompStrings s1 s2 = true -> length s1 = s2 by induction on s1:
in the case where s1 is the EmptyString, let's look at the shape of s2:
s2 is the EmptyString, then both lengths are equal to 0, so reflexivity.;
s2 is a String _ _, so there is a contradiction in the hypothesis, shown by inversion C.;
in the case where s1 is a String char1 rest1, let's look at the shape of s2, supposing the property true for rest:
s2 is the EmptyString, so there is a contradiction in the hypothesis, show by inversion C.;
s2 is a String char2 rest2, then length s1 = S (length rest1) and length s2 = S (length rest2), therefore we need to prove S (length rest1) = S (length rest2). Also, the hypothesis C simplifies into C: CompStrings rest1 rest2 = true. It is the perfect occasion to use the induction hypothesis to prove that length rest1 = length rest2, and then use that result somehow to prove the goal.
Note that for that last step, there are many ways to proceed to prove S (length rest1) = S (length rest2). One of which is using f_equal. which asks you to prove a pairwise equality between the parameters of the constructor. You could also use a rewrite (IHs1 _ C). then use reflexivity on that goal.
Hopefully this will help you not only solve this particular goal, but get a first understanding at proofs by induction!
To close on this, here are two interesting links.
This presents the basics of induction (see paragraph "Induction on lists").
This explains, better than me, why and how to generalize your induction hypotheses. You'll learn how to solve the goal where I did intros s1 s2 C. by putting back the s2 in the goal before starting the induction, using the tactic generalize (dependent).
In general, I'd recommend reading the whole book. It's slow-paced and very didactic.