in f# match statement how do I match to the type byte[]? - ado.net

I'm trying to lookup DbType enumeration values from .net types. I'm using a match statement. However I cannot figure out how to match on the type byte[].
let dbType x =
match x with
| :? Int64 -> DbType.Int64
| :? Byte[] -> DbType.Binary // this gives an error
| _ -> DbType.Object
If there is a better way to map these types, I would be open to suggestions.

byte[], byte array, and array<byte> are all synonymous, but in this context only the last will work without parentheses:
let dbType (x:obj) =
match x with
| :? (byte[]) -> DbType.Binary
| :? (byte array) -> DbType.Binary // equivalent to above
| :? array<byte> -> DbType.Binary // equivalent to above
| :? int64 -> DbType.Int64
| _ -> DbType.Object

Related

How do you override `GetHashCode()` idiomatically for an algebraic data type?

I have an algebraic type of the following form:
type Example =
| Ctor0 of int
| Ctor1 of Example * Example
| Ctor2 of Example * Example
| Ctor3 of Example list
If I need to hash a value of type Example, I can use the default method: myValue.GetHashCode() or use hash which does the same thing. Now, suppose I want to define my own hash function for some reason because I need a special hash for the Ctor3 constructor, then I would override the GethashCode() method:
type Example =
| Ctor0 of int
| Ctor1 of Example * Example
| Ctor2 of Example * Example
| Ctor3 of Example list
override this.GethashCode() =
match this with
| Ctor0 (n) -> hash n (* The default `hash` is sufficient here *)
| ...
| Ctor3 (xs) -> myCustomHash xs
I need to define a hash value for Ctor1 and Ctor2, but their form is similar and using hash would not help. Indeed, for example one could define Ctor1(Ctor 7, Ctor 4) and Ctor2(Ctor 7, Ctor 4) if, in GetHashCode(), I hash only the value of the constructors, I would have the same hash for two different values.
override this.GetHashCode() =
match this with
| Ctor0 (n) -> hash n
| Ctor3 (xs) -> myCustomHash xs
(* I could do something like that: *)
| Ctor1 (a, b) -> hash a + hash b (* or maybe 1 + hash (a, b) *)
| Ctor2 (a, b) -> hash a - hash b (* 2 + hash (a, b) *)
The latter code does not seem to me very satisfactory... In such a situation, and assuming I have a large number of constructors, how am I supposed to define a hash function that of course produces a different value for each constructor (with a high probability anyway)?
I don't know much about hash algorithms, so my question may be very silly, but an indication of the idiomatic way to define (override) the hash function for this style of situation would be appreciated.
PS: I know you have to use CustomEquality and NoComparison, I'm just talking about how to do what I want here.
The recommended way to combine hash codes since .NET Standard 2.1 is using System.HashCode.Combine(). To differentiate between cases, you can add an integer argument.
override this.GetHashCode() =
match this with
| Ctor0 n -> HashCode.Combine(0, n)
| Ctor1 (a, b) -> HashCode.Combine(1, a, b)
| Ctor2 (a, b) -> HashCode.Combine(2, a, b)
| Ctor3 xs -> HashCode.Combine(3, myCustomHash xs)
I added the integer argument in all cases for consistency, but I think you're right that Ctor0 and Ctor3 don't really need it.
If you need to be compatible with older .NET versions, you can rely on hash for tuples instead. (I'm using struct tuples here which should allocate less than normal tuples)
override this.GetHashCode() =
match this with
| Ctor0 n -> hash struct(0, n)
| Ctor1 (a, b) -> hash struct(1, a, b)
| Ctor2 (a, b) -> hash struct(2, a, b)
| Ctor3 xs -> hash struct(3, myCustomHash xs)

Ocaml: usage of match with [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm trying to write some code in ocaml that parses the following c code for predefined functions
main {
x = function1(3);
x = function2(x,2);
}
So here is my ocaml code:
match expr with
|Bool(b) ->( match b with
|true -> (*do things*)
|false -> (*do things*) )
|Call(f, args) ->( match f with
| function1(x) -> (*do things with x*)
| function2(x,n) -> (*do things with x and n*)
|_ -> failwith "not implemented yet " )
For the time being, let's assume the language I'm parsing only has two functions, I would like to retrieve the arguments in the C code in order to use them in my ocaml program but I get a syntax error at the line containing the match with sth()
Removing the parentheses and the arguments make the program run but this is not what I want, I need to arguments...
I don't understand what is wrong with my matching could someone please explain the right syntax to me?
Thanks in advance
The pattern matching only match type constructors.
The first thing to do is to write down the type you want to match :
type typ =
| Bool of bool
| Function1 of int
| Function2 of int * int
Then your fonction will look like this one (combining all the differents case inside a single one match case):
let eval
: typ -> unit (* The function signature *)
= fun t ->
match t with
| Bool true -> print_endline "true"
| Bool false -> print_endline "false"
| Function1 number -> print_endline (string_of_int number)
| Function2 (n1, n2) -> print_endline (string_of_int (n1 + n2))

Type checking error useing random in purescript

With the following code insertRnd works properly but I can't get scramble or anything else that uses insertRnd to compile:
scramble :: ∀ eff. String -> Eff (random :: RANDOM | eff) String
scramble s = foldl insertRnd (take 1 s) (drop 1 s)
insertRnd :: ∀ eff. String -> String -> Eff (random :: RANDOM | eff) String
insertRnd st ch = do
n <- randomInt 0 $ length st
pure $ insertAt n ch st
I get the following error message
Could not match type
Eff
( random :: RANDOM
| t2
)
String
with type
String
while checking that type forall eff.
String
-> String
-> Eff
( random :: RANDOM
| eff
)
String
is at least as general as type t0 -> t1 -> t0
while checking that expression insertRnd
has type t0 -> t1 -> t0
in value declaration scramble
where t0 is an unknown type
t1 is an unknown type
t2 is an unknown type
What am I doing wrong?
First, your insertRnd itself doesn't compile for me, because there is no function insertAt :: Int -> String -> String -> String (or even Int -> Char -> String -> String, see below). There is such function for arrays and lists and some other stuff, but not for strings. I will just assume here that you wrote such function yourself and it exists in your code.
Second, even if it does compile, it has wrong signature for a fold: you're trying to fold over a String, which contains Chars, which means that the folding function's second argument must be a Char. So here I'll assume that your insertRnd actually has the following signature:
insertRnd :: ∀ eff. String -> Char -> Eff (random :: RANDOM | eff) String
Third, you can't actually foldl over a String, because String doesn't have an instance of Foldable. To fold over the characters of a string, you need to first convert the string to an array (or some other container) of Char. Fortunately, there is a helpful function for that - toCharArray.
Fourth, your claim about not being able to compile "anything else that uses insertRnd" is probably too broad. Here's a perfectly compilable example of "anything else" that uses insertRnd:
main = launchAff do
x <- liftEff $ insertRnd "abcd" 'x'
log x
And finally, the reason that your foldl doesn't compile is that foldl expects a pure function a -> b -> a as first argument, but you're giving it an effectful function a -> b -> Eff _ a. No wonder there is a type mismatch!
The effectful analog of foldl is foldM. This function does a similar thing, except it chains the calls within a monad instead of doing pure functional composition. For example:
foldM insertRnd "a" ['b', 'c', 'd']
Applying all of the above to your code, here's the final version (assuming the existence of insertAt :: Int -> Char -> String -> String):
scramble :: ∀ eff. String -> Eff (random :: RANDOM | eff) String
scramble s = foldM insertRnd (take 1 s) (toCharArray $ drop 1 s)
insertRnd :: ∀ eff. String -> Char -> Eff (random :: RANDOM | eff) String
insertRnd st ch = do
n <- randomInt 0 $ length st
pure $ insertAt n ch st

OCaml option return value and option matching

I want to write a function that accepts values of a custom class myType, and returns myType option. Not sure if my problem is with signature, content or return values.
For example, I've tried to write the following (it's simplified and have no real meaning):
let rec myFunc (t:myType) myType option =
let t2 = myFunc t in
match t2 with
| None -> None
| _ -> t
And I'm getting the following compilation error:
Error: This pattern matches values of type 'a option
but a pattern was expected which matches values of type 'b -> 'c -> 'd
Not sure what's wrong with my syntax or where I'm misunderstanding OCaml.
I only see a missing colon and Some:
let rec myFunc (t:myType): myType option =
let t2 = myFunc t in
match t2 with
| None -> None
| _ -> Some t
Slightly streamlined version:
let rec myFunc (t:myType): myType option =
match myFunc t with
| None -> None
| _ -> Some t

Scala only language with overloaded extractors?

In at least some of the ML family languages, you can define records on which you can perform pattern matching e.g. http://learnyouahaskell.com/making-our-own-types-and-typeclasses - the basic idea is that you define a record type with named fields, a constructor is automatically created with those fields as parameters so you can create records of that type, and an extractor is automatically created with those fields as parameters so you can pattern match on records of that type.
Scala goes a step further and allows the fields stored in the record, the constructor parameters and the extractor parameters to be decoupled from each other e.g. http://daily-scala.blogspot.com/2009/11/overloaded-unapply.html - in this it is living up to its goal of supporting both object-oriented and functional programming. (Object-oriented languages of course normally allow stored fields and constructor parameters to be decoupled, though they don't normally have extractors.)
Are there any other languages that have pattern matching and allow such decoupling?
Has anything been written about the pros and cons of such decoupling?
I admit that I don't have 100% of the background required to understand your question, but I can say that F# has a feature called "Active Patterns" that it seems could be used to build the same functionality that your daily-scala link demonstrates.
Is that in the neighborhood of what you're looking for?
No, F# also provides that feature.
Examples in the second article can be implemented using Partial Active Patterns:
let (|String|_|) = function "s" -> Some "yay" | _ -> None
let (|Int|_|) = function 1 -> Some "hmm" | _ -> None
let (|StringList|_|) = function "x" -> Some [1; 2; 3] | _ -> None
let (|IntList|_|) = function 1 -> Some ["one"; "two"] | _ -> None
match 1 with
| Int s -> printfn "%O" s
| _ -> printfn "Unmatched"
match "s" with
| String s -> printfn "%O" s
| _ -> printfn "Unmatched"
match "x" with
| StringList [x; y; z] -> printfn "%O" (x, y, z)
| _ -> printfn "Unmatched"
match 1 with
| IntList [x; y] -> printfn "%O" (x, y)
| _ -> printfn "Unmatched"
Active Patterns is a powerful technique, you can even write it in a recursive way. Its combination with pattern matching provides a convenient toolkit for destructuring data. However, pattern matching is inexhaustive so you have to use wildcard(_) as the last pattern.
For reference, Don Syme (the inventor of F#) wrote a paper about F#'s "Active Patterns": Extensible Pattern Matching Via a Lightweight Language Extension – Syme, et al.
There is a long history of first class patterns in typed functional languages.
In Haskell land, we use the -XViewPatterns extension for programmatic patterns.
The first true view patterns go back to Phil Wadler's 1987 paper on views