How do I display data using REPL?
I'm sure this is a very basic question.
I referenced this.
I pasted the code in the REPL window. But I'm not seeing the cards display.
type Suit = | Spades
| Diamonds
| Clubs
| Hearts
type Face = |Two | Three | Four | Five
| Six | Seven | Eight | Nine | Ten
| Jack | Queen | King | Ace
type Card = {Face: Face; Suit: Suit}
type Deal = | Hand of Card * Card
| Hit of Card
let dealPlayer() = Hit{Face=Two; Suit=Spades}
dealPlayer |> printfn "%A"
Result:
val it : unit = ()
Update
When I update the code to the following:
let dealPlayer() = Hit{Face=Two; Suit=Spades}
dealPlayer() |> printfn "%A"
I still get this:
val dealPlayer : unit -> Deal val it : unit = ()
You don't have to explicitly print values in FSI; it does that for you automatically when you evaluate an expression:
> dealPlayer ();;
val it : Deal = Hit {Face = Two;
Suit = Spades;}
If you don't bind the expression to a named value, it'll be bound to the implicit value it, as shown above.
FSI nicely formats and displays the functional data types: records, discriminated unions, lists, arrays. For objects, it'll typically call ToString() in order to get a display value.
You aren't evaluating the `dealPlayer' function.
Change
dealPlayer |> printfn "%A"
to
dealPlayer() |> printfn "%A"
Note: You'll probably want to run the line dealPlayer() |> printfn "%A";; after the rest of your code, otherwise the printed text will appear right at the top of the return from the REPL, followed by a printout of the types you've declared and the type signatures of the functions you've declared.
Related
I have the following Discriminated Union (DU) declaration:
type Book =
| Dictionary of string[]
| Novel of int[]
| Comics of bool[]
An example:
let x = Dictionary [|"a"; "b"|]
How can I extract the length of the array inside without doing pattern matching and without caring about the data type of the array (in this case: string, int, bool). Note: I have no control over the DU declaration; as a result, I can't write new member method within Book, like getArrayLength()
Of course, we can do it in some way as followed:
match x with
| Dictionary (x: _[]) -> x |> Array.length
| Novel (x: _[]) -> x |> Array.length
| Comics (x: _[]) -> x |> Array.length
But typing x |> Array.length a lot is incovenient. This is a simple example, but we can think of a general problem:
type Animal =
| Dog of DogClass
| Cat of CatClass
| Cow of CowClass
...
... and DogClass, CatClass, etc. may share something. We want to get that shared thing. E.g. those classes inherit from AnimalClass, within which there is countLegs() method. Suppsed there are many animals, pattern matching for all of them while the code block after -> is almost the same. I love the principle DRY (Don't Repeat Yourself).
Is there any convenient way to tackle such problem?
==
EDITED 21.10.2019
I was also looking for some syntax like:
let numEles =
match x with
| _ (arr: _[]) -> x |> Array.Length
| _ -> failwith "No identifiers with fields as Array."
let numLegs =
match anAnimall with
| _ (animal: ?> Animal) -> animal.countLegs()
| _ -> failwith "Can't count legs because of not being an animal."
I think this still follows the spirit of matching, but seem like this approach is not supported.
Realistically, there's no getting around pattern matching here. DUs were, in a way, built for it. Since you don't control the type, you can always add a type extension:
type Book with
member this.Length =
match this with
| Dictionary d -> d.Length
| Novel n -> n.Length
| Comics c -> c.Length
let x = Dictionary [|"a"; "b"|]
printfn "%d" x.Length // Prints 2
Though it's also equally valid to define a Book module with a length function on it if you prefer that:
module Book =
let length b =
match b with
| Dictionary d -> d.Length
| Novel n -> n.Length
| Comics c -> c.Length
let x = Dictionary [|"a"; "b"|]
printfn "%d" (x |> Book.length) // prints 2
But you'll need to write a pattern match expression on the Book type at least once. The fact that every case is made up of data that all has the same property doesn't really help the fact that you need to still identify every case individually.
I just don't understand what the compiler is trying to tell me here:
let someCard = getFirstCard hand
Error:
This expression was expected to have type
Card * Card
but here has type
(Card * Card) option
I then tried this:
let getFirstCard (hand:Card*Card) = function
| card1, card2 -> Some(card1)
But I get the same error.
I just don't get the Options template.
I continue to struggle with this.
My code is below:
type Suit = | Spades| Clubs | Diamonds | Hearts
type Face = | Two | Three | Four | Five
| Six | Seven | Eight | Nine | Ten
| Jack | Queen | King | Ace
type Card = {Face:Face; Suit:Suit}
type Deal = | Hand of Card * Card
| Hit of Card
let private suits = [Spades; Clubs; Diamonds ; Hearts]
let private faces = [Two; Three; Four; Five; Six; Seven; Eight; Nine; Ten;
Jack; Queen; King; Ace]
let deck = [for suit in suits do
for face in faces do
yield {Face=face; Suit=suit}]
let hitPlayer (deck:Card list) =
(deck.Head, deck.Tail)
let shuffle xs =
let swap i j (array : _[]) =
let tmp = array.[i]
array.[i] <- array.[j]
array.[j] <- tmp
let rnd = System.Random()
let xArray = Seq.toArray xs
let n = Array.length xArray
for i in [0..(n-2)] do
let j = rnd.Next(i, n-1)
swap i j xArray
xArray |> Seq.toList
let deal = function
| card1::card2::remaining -> Some(card1, card2), remaining
| _ -> None, [];;
let getFirstCard (hand:Card*Card) = function
| card1, card2 -> card1
let hand, deckRemaining = deal (shuffle deck);;
let someCard = getFirstCard hand
The getFirstCard function has the type Card * Card -> 'a * 'b -> 'a (which, BTW, looks strange, to say the least). It does, however, expect its first parameter to be of the type Card * Card.
hand, on the other hand (pun intended), has the type (Card * Card) option. This means that it may contain a Card * Card value, but it also may not. You'll need to tell your program how to deal with both cases.
As we've discussed before, the Option type is an 'elevated world', and the most appropriate strategy is to stay in that elevated world until you can deal with all cases. Here's one way to do it:
let someCard = hand |> Option.map getFirstCard
This still doesn't work because of the weird implementation of getFirstCard.
Looking at the implementation of getFirstCard, though, I get the impression that what you attempt to do is to get the first card out of a tuple of cards. This, however, can be written as:
let getFirstCard (card1, card2) = card1
That function is already built into F#, although there's nothing wrong with giving it a domain-specific name. In that case, though, I'd suggest aliasing it instead:
let getFirstCard = fst
Given one of the two above definitions of getFirstCard, the expression
let someCard = hand |> Option.map getFirstCard
gives you a someCard value of the type Card option. You'll notice that we've stayed in the 'elevated' Option world.
Specifically, though, someCard has this value:
> someCard;;
val it : Card option = Some {Face = King;
Suit = Clubs;}
You'll note that it isn't just King of Clubs, but Some King of Clubs.
Try this :
let getFirstCard (hand) =
match hand with
| Some(x) -> Some (fst x)
|_ -> None
let hand, deckRemaining = deal (shuffle deck);;
let someCard = getFirstCard hand
It compiles & runs for me.
Actually, function getFirstCard could be renamed as a generic fun on tuples :
let getFirstOfTupleOption tup =
match tup with
| Some (x) -> Some (fst x)
| _ -> None
Alternatively, you may want explicit type restriction on your domain with :
let getFirstCard (hand:(Card*Card) option) =
match hand with
| Some(x) -> Some (fst x)
|_ -> None
I have a function, which can returns different types, and I use discriminated union for this. What I need, is to have conversion from one type in discriminated union to another type.
Also some of the types can be convertable to all other types (String), but some of the types can be converted only to String (MyCustomType)
For this I've added member method ConvertTo to the ResultType:
type MyTypes =
| Boolean = 1
| Integer = 2
| Decimal = 3
| Double = 4
| String = 5
| MyCustomType = 6
type ResultType =
| Boolean of bool
| Integer of int
| Decimal of decimal
| Double of double
| String of string
| MyCustomType of MyCustomType
with
member this.ConvertTo(newType: MyTypes) =
match this with
| ResultType.Boolean(value) ->
match newType with
| MyTypes.Boolean ->
this
| MyTypes.Integer ->
ResultType.Integer(if value then 1 else 0)
...
| ResultType.MyCustomType(value) ->
match newType with
| MyTypes.MyCustomType ->
this
| MyTypes.String ->
ResultType.String(value.ToString())
| _ ->
failwithf "Conversion from MyCustomType to %s is not supported" (newType.ToString())
I don't like such construction, because if I add more types, this requires me to do many changes: MyTypes, ResultType and also in several places in the ConvertTo member function.
Can anybody suggest better solution for such types conversion?
Thanks in advance
With a slightly different design, it is possible to exploit System.Convert.ChangeType and the fact that the constructors of discriminated unions are actually functions:
// statically typed wrapper for System.Convert.ChangeType
let conv a : 'T = System.Convert.ChangeType(a, typeof<'T>) :?> 'T
type MyCustomType() = class end
type ResultType =
| Boolean of bool
| Integer of int
| Decimal of decimal
| Double of double
| String of string
| MyCustomType of MyCustomType
with
member this.ConvertTo (newType:'T->ResultType) =
match this with
| Boolean b -> newType( conv b )
| Integer i -> newType( conv i )
| Decimal d -> newType( conv d )
| Double d -> newType( conv d )
| String s -> newType( conv s )
| MyCustomType m ->
if typeof<'T> <> typeof<string> then
raise (new System.InvalidCastException("MyCustomType can only be converted to String"))
else
String (m.ToString())
let i = Integer 42
let b = i.ConvertTo Boolean
printfn "%A" b
let d = i.ConvertTo Decimal
printfn "%A" d
let d2 = i.ConvertTo Double
printfn "%A" d2
let s = i.ConvertTo String
printfn "%A" s
//let mi = i.ConvertTo MyCustomType // throws InvalidCastException
let m = MyCustomType (new MyCustomType())
let sm = m.ConvertTo String
printfn "%A" sm
//let im = m.ConvertTo Integer // throws InvalidCastException
EDIT: Once you add more custom types, this will not help much.
Maybe you should make your custom types implement IConvertible. Then you can remove the special case code from ConvertTo and completely rely on System.Convert.ChangeType.
You would still have to extend every custom type's ToObject implementation whenever you add a new custom type. Whether that really is better than a central ConvertTofunction is debatable.
Why are you wanting to do type conversion to begin with? Discriminated Unions are a good way of hiding type information until you need it and abstract complexity away. Generally you have a match statement in a function that consumes this type and then you only cast if you need to.
If you're trying to make some type of parser or language engine then you have no choice but to define all the cast or at least their error states. If you wouldn't mind elaborating on why / what you would use this for, maybe I could suggest another approach.
An aside: F# and .NET in general doesn't support overloading of return types.
I've spent a few hours trying to get to grips with F# Quotations, but I've come across a bit of a road block. My requirement is to take simple functions (just integers,+,-,/,*) out of a discriminated union type and generate an expression tree that will eventually be used to generate C code. I know this is possible using Quotations with 'direct' functions.
My problem is that the expression tree seems to terminate with a "Value", and I can't figure out how to traverse into that value.
My questions is
whether this is actually possible in this situation? or are there any other approaches that are worth considering.
type FuncType =
| A of (int -> int -> int)
| B
| C
[<ReflectedDefinition>]
let add x y = x + y
let myFunc1 = A (fun x y -> x + y )
let myFunc2 = A add
let thefunc expr =
match expr with
| A(x) ->
<# x #>
| _ ->
failwith "fail"
printfn "%A" (thefunc myFunc1) // prints "Value (<fun:myFunc1#14>)"
printfn "%A" (thefunc myFunc2) // prints "Value (<fun:myFunc2#15>)"
printfn "%A" <# fun x y -> x + y #> // generates usable expression tree
Quotations represent the F# code that was quoted syntactically. This means that if you write something like <# x #>, the quotation will contain just Value case specifying that you quoted something which has the specified value. (Variables are automatically replaced with values if the variable is defined outside of the quotation).
You can only get quotation of code that was explicitly quoted using <# .. #> or of a function that was marked as ReflectedDefinition and is referred to by name in a quotation (e.g. <# add #> but not for example let f = add in <# f #>).
To be able to do what your snippet suggests, you'll need to store quotations in your FuncType too (so that the lambda function that you write is also quoted and you can get its body). Something like:
type FuncType =
| A of Expr<int -> int -> int>
| B | C
[<ReflectedDefinition>]
let add x y = x + y
let myFunc1 = A <# fun x y -> x + y #>
let myFunc2 = A <# add #>
let thefunc expr =
match expr with
| A(x) -> x
| _ -> failwith "fail"
This should work for functions marked as ReflectedDefinition too. To extract the body of the function you need to add something like (you'll need to substitute arguments of the function for parameters, but this should give you some idea):
match expr with
| Lambdas(_, body) ->
match body with
| Call(_, mi, _) when Expr.TryGetReflectedDefinition(mi) <> None ->
let func = Expr.TryGetReflectedDefinition(mi)
match func with
| Some(Lambdas(_, body)) ->
// 'body' is the quotation of the body
| _ -> failwith "Not supported function"
| _ -> failwith "Not supported function"
| _ -> failwith "Not supported expression"
After reading Chris' answer to F# - public literal and the blog post at http://blogs.msdn.com/b/chrsmith/archive/2008/10/03/f-zen-the-literal-attribute.aspx I don't get why the following is not working:
[<Literal>]
let one = 1
[<Literal>]
let two = 2
let trymatch x =
match x with
| one -> printfn "%A" one
| two -> printfn "%A" two
| _ -> printfn "none"
trymatch 3
This keeps printing "3", although I think it shouldn't. What is it that I don't see here?
I think that literals need to be Uppercase. The following works fine:
[<Literal>]
let One = 1
[<Literal>]
let Two = 2
let trymatch x =
match x with
| One -> printfn "%A" One
| Two -> printfn "%A" Two
| _ -> printfn "none"
trymatch 3
In addition, if you want a nice general solution for this without using literals, you can define a parameterized active pattern like this:
let (|Equals|_|) expected actual =
if actual = expected then Some() else None
And then just write
let one = 1
let two = 2
let trymatch x =
match x with
| Equals one -> printfn "%A" one
| Equals two -> printfn "%A" two
| _ -> printfn "none"
The other answers are right - you must start your identifier with an uppercase letter. See section 7.1.2 of the spec (Named Patterns), which states that:
If long-ident is a single identifier that does not begin with an uppercase character then it is always interpreted as a variable-binding pattern and represents a variable that is bound by the pattern
Also if you don't want to have Uppercase literals you can put them in a module (here named Const):
module Const =
[<Literal>]
let one = 1
[<Literal>]
let two = 2
let trymatch x =
match x with
| Const.one -> printfn "%A" Const.one
| Const.two -> printfn "%A" Const.two
| _ -> printfn "none"
trymatch 3
Don't ask me why, but it works when you write your literals uppercase:
[<Literal>]
let One = 1
[<Literal>]
let Two = 2
let trymatch (x:int) =
match x with
| One -> printfn "%A" One
| Two -> printfn "%A" Two
| _ -> printfn "none"
trymatch 3