OCaml option return value and option matching - match

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

Related

Mapping homogeneous record type

Suppose we have a record type that is homogeneous.
type RecI = { a :: Int, b :: Int, c :: Int, d :: Int, e :: Int }
We want to get from it type with the same keys but different value type:
type RecS = { a :: String, b :: String, c :: String, d :: String, e :: String }
Is it possible to get RecS type without explicitly defining all the keys from RecI?
And the second part of the question, what is the best way to implement mapping function from one type to another:
mapItoS :: (Int -> String) -> RecI -> RecS
?
To get a free-ish conversion from Int to String at type level, just give your record a parameter, then instantiate it with Int to get RecI and with String to get RecS:
type Rec a = { a :: a, b :: a, c :: a, d :: a, e :: a }
type RecI = Rec Int
type RecS = Rec String
To implement mapItoS, you can first convert to a Foreign.Object using fromHomogeneous, then map the function over it, then convert back to the record.
Unfortunately there is no toHomogeneous function, because in general you can't be sure that the Foreign.Object actually contains all required keys. But no matter: in this particular case you can be sure that it does, so you can get away with unsafeCoerce:
mapItoS :: forall a b. (a -> b) -> Rec a -> Rec b
mapItoS f = fromHomogeneous >>> map f >>> unsafeCoerce
A small self plug which is strictly relevant to the question :-P I've just published a library which provides many instances which allow a PureScripter to work with homogeneous Record and Variant:
https://pursuit.purescript.org/packages/purescript-homogeneous
I think it should have much better inference than solutions like heterogeneous. Please check it out and let me know what do you think.

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))

How to convert partial functions to safe(Maybe) functions?

I want it to use library-defined partialfunc more convenient, or write callback with partial pattern-matching.
like this,
partialMaybe :: forall a b. (Partial => a -> b) -> a -> Maybe b
I couldn't find similar in some major libraries.
How to define it? or already defined in libs?
data ABC a = A a | B a | C a
f1 = someHigherOrderFunc $ partialMaybe \(A a) -> someFunc a -- if not 'A', return Nothing.
-- same as
f2 = someHigherOrderFunc $ case _ of A a -> Just $ someFunc a
_ -> Nothing -- requires line break, seems syntax redundant...
using: purescript 0.11.6
Edit:
I did it...
partialMaybe :: forall a b. (Partial => a -> b) -> a -> Maybe b
partialMaybe f a = runPure $ catchException (const $ pure Nothing) (Just <<< unsafePartial f <$> pure a)
this is...umm...very ugly. it's not.
'Failed pattern match' exception is thrown by the purescript.
so I think it should be able to handle by purescript.
Can't do it?
If you want an exception if a case is missed, use Partial. If you want otherwise, use Maybe or Either or another appropriate sum type.
You can catch the exception thrown from a failed pattern match. There is no way for a failed pattern match to not throw an exception.

infinite type inferred due to pattern variable

Using a pattern variable that names an entire case expression makes the difference between compiling correctly and the error "An infinite type was inferred for an expression". The following compiles correctly:
m = case Left "anything" of
e#(Left err) -> Left err
(Right f) -> case lookup "key" f of
Nothing -> Left "something else"
(Just x) -> Right x
However, if we use the pattern variable e (substituting e for "Left err", functionally equivalent), the compiler flags an error:
m = case Left "anything" of
e#(Left err) -> e
(Right f) -> case lookup "key" f of
Nothing -> Left "something else"
(Just x) -> Right x
"An infinite type was inferred for an expression: StrMap t1 while trying to match type t1 with type StrMap t1 while checking that expression case ((lookup "key") f) ...
I understand that matching StrMap t1 with t1 is problematic. I do not understand why this happens. Also, in my original code the message did not refer to infinite types at all. Here is the relevant extract:
retrieveDomeinResourceDefinition :: forall e.
ResourceId
-> Namespace
-> (AsyncDomeinFile e (Either String PropDefs))
retrieveDomeinResourceDefinition id ns = do
df <- retrieveDomeinFile (namespaceToDomeinFileName ns)
case df of
e#(Left err) -> pure $ e
(Right f) -> case lookup id f of
Nothing -> pure $ Left ("retrieveDomeinResourceDefinition: cannot find definition of " <> id <> " in DomeinFile for " <> ns)
(Just propDefs) -> pure (Right propDefs)
retrieveDomeinFile :: forall e. Namespace -> AsyncDomeinFile e (Either String DomeinFile)
newtype PropDefs = PropDefs (StrMap Json)
Now here the compiler tells me: "Could not match type: PropDefs with type StrMap PropDefs..." It appears as if the compiler does not notice the lookup expression. In fact, when I replace "pure (Right propDefs)" with "pure (Right f)", the error goes away (and another appears on the line binding df, which I understand).
Now I write this up I notice the similarity between 'trying to match type t1 with type StrMap t1' and 'could not match type: PropDefs with StrMap PropDefs'. Still, I don't see why using e introduces this problem.
Using the value from a pattern match that way may be functionally equivalent, but the types are not - the type system doesn't have the evidence that the type variable for the Right can be ignored.
Using the types in your second example - when you pattern match e#(Left err), the type of e will be Either String DomeinFile - but you want an Either String PropDefs. The pattern match does not "free up" the type variable on the right, which is why you have to reconstruct the Left with the error again.

in f# match statement how do I match to the type byte[]?

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