I wanted this kind of expression in OCaml
let wrapper obj f = fun raw -> f (new obj raw)
But I get a compiler error of Unbound class obj but so what, why isn't the compiler satisfied with creating this function which just says call a function on this object which happens to take one init arg.
Pass a function that constructs the object. For a one-argument class foo you can use new foo to get that function.
let wrapper make_obj f raw = f (make_obj raw)
class foo (x) = object
method y = x + 1
end
let answer = wrapper (new foo) (fun o -> o#y) 2
Here, wrapper has a very general type that doesn't mention objects at all. If you want to make it clear that an object constructor is expected as the argument, you can restrict the type with an annotation:
let wrapper (make_obj: (_ -> < .. >)) f raw = f (make_obj raw)
One way to look at this is that an OCaml class is a type, not a value. So you can't write a function in OCaml that accepts a class as a parameter.
Here's a session:
$ ocaml
OCaml version 4.02.1
# class abc = object method m = 12 end;;
class abc : object method m : int end
# abc;;
Error: Unbound value abc
# let f (x: abc) = x#m ;;
val f : abc -> int = <fun>
# f (new abc);;
- : int = 12
As you can see, abc is a type. Not a value.
In other languages, classes are values. But not in OCaml.
Related
I have a struct Context that as a type takes an association list from string to a custom type process.
I'm trying to pattern match to see if my struct is empty (this seems to work fine) however checking whether my struct contains elements is giving me the following error.
File "src/main.ml", line 131, characters 13-30:
131 | | Context.((ext_ref,prc)::tl) ->
^^^^^^^^^^^^^^^^^
Error: This pattern matches values of type 'a list
but a pattern was expected which matches values of type t
Here is the code that won't compile:
(* Finds a recv corresponding to a send stmt *)
let rec find_recv (ctx: Context.t) (external_ref:variable) =
match ctx with
| Context.(empty) -> None
| Context.((ext_ref,prc)::tl) ->
begin
match prc with
| Prc(_, _,Recv(_,_,chn,_)) -> if chn = external_ref then Some prc else find_recv tl external_ref
|_ -> find_recv tl external_ref
end
Here is the signature for the 'Context' struct.
module type Context = sig
type t
val empty : t
val lookup : t -> string -> process
val extend : t->string ->process -> t
val filter : t->string ->t
end
Here is the instantiation of my Context module:
(** Instantiating a Process Table *)
module Context : Context = struct
type t = (string * process) list
let empty = []
let lookup (ctx:t) (x:string): process=
let chck = List.assoc_opt x ctx in match chck with
|Some i -> i
|None -> Null("")
let extend (ctx:t) (x:string) (ty:process) =
(x, ty) :: ctx
let filter ctx x =
List.remove_assoc x ctx
end
I got this code from the Real World Ocaml book.
Given the constraints of your Context signature, type t within the Context module is abstract.
Within the module, your functions know that empty is a list. However, outside of it, empty is merely of abstract type Context.t.
Let's look at a simpler example:
utop # module type S =
sig
type t
val empty : t
end
module M : S =
struct
type t = int list
let empty = []
end;;
module type S = sig type t val empty : t end
module M : S
utop # M.empty;;
- : M.t = <abstr>
utop # match M.empty with [] -> "hello" | _ -> "world";;
Error: This pattern matches values of type 'a list
but a pattern was expected which matches values of type M.t
M.t is abstract. We know it exists, but not how it is implemented. This abstraction is frequently useful in designing applications.
It is possible to break this abstraction. Whether it's a good idea is a matter of opinion and outside of Stack Overflow's scope.
utop # module M2 : S with type t = int list =
struct
type t = int list
let empty = []
end;;
module M2 : sig type t = int list val empty : t end
utop # match M2.empty with [] -> "hello" | _ -> "world";;
- : string = "hello"
As kindly pointed out by #glennsl and as is explained better than I can in this thread Unbound constructor error when using module signature
My problem can be solved by including the find_recv function within the Modules signature as below.
module type Context = sig
type t
val empty : t
val lookup : t -> string -> process
val extend : t->string ->process -> t
val filter : t->string ->t
val find_recv: t -> variable -> process option
end
Obviously this must then be instantiated before use.
I'm wondering whether we can use where outside a function?
e.g.
fun::Int->Int
fun n = n + 1
main = do
fun x where x = 30
Obviously it does't work when I compile it,
I want to declare x as local variable for fun only
Your function has the wrong type to be used as the final expression in a do block. It needs to return an Monad m => m Int value, not simply an Int. As main (in its usual use) is required to be an IO action, this means m should be IO.
fun :: Int -> IO Int
fun n = return (n + 1)
A let would be more appropriate than a where in this case, though.
main = do
let x = 30 in fun x
Now, x is in scope only for the call to fun. If you wrote
main = do
let x = 30
fun x
then x is technically in scope for the rest of the do block, not just the call to fun. Despite sharing the same keyword let, there is a distinct difference between a let in a do block and a regular let expression. (The relationship is that
do
let name = value
foo
is equivalent to
let name = value
in do
foo
)
Note that do itself does not create a monadic value; it is simply syntactic sugar for various operators which assume monadic properties. A quick overview:
do { x <- y; foo x; } becomes y >>= (\x -> foo x).
do { foo; bar; } becomes foo >> bar.
do { let x = y; foo; } becomes let x = y in do foo
do foo becomes foo.
Most relevant to your code is rule 4; a single expression in a do block is equivalent to the expression by itself, meaning you can strip the do. Only after the do block is desugared does Haskell begin to type-check the result.
I have the following code in F# (it's from a book)
open System.Collections.Generic
type Table<'T, 'U> =
abstract Item : 'T -> 'U with get
abstract Discard : unit -> unit
let memoizeAndPermitDiscard f =
let lookasideTable = new Dictionary<_, _>(HashIdentity.Structural)
{new Table<'T, 'U> with
member t.Item
with get(n) =
if lookasideTable.ContainsKey(n) then
lookasideTable.[n]
else
let res = f n
lookasideTable.Add(n, res)
res
member t.Discard() =
lookasideTable.Clear()}
let rec fibFast =
memoizeAndPermitDiscard (fun n ->
printfn "computing fibFast %d" n
if n <= 2 then 1 else fibFast.[n - 1] + fibFast.[n - 2])
As we can see the abstract type Table take it's implementation in the function memoizeAndPermitDiscard. Can Haskell do the same?
Apologies in advance: I'm not an F# expert, so I may be misreading the F# code. But if I'm reading it right it's fairly straightforward to translate to Haskell:
data Table t u = Table { get :: t -> IO u, discard :: IO () }
memoize :: Hashable t => (t -> u) -> IO (Table t u)
memoize f = do
tbl <- newHashTable
return Table
{ get = \t -> do
result <- lookupHashTable t tbl
case result of
Nothing -> let u = f t in writeHashTable t u tbl >> return u
Just u -> return u
, discard = clearHashTable tbl
}
I'm assuming some suitable hash table implementation here that offers newHashTable, lookupHashTable, writeHashTable, and clearHashTable. Implementing these (or suggesting a library that offers them) is sort of beside the point of the question, I think.
I'm not an F# expert either, but I believe what you're describing is where you create a anonymous single-use subclass, by declaring in at the point where you create an object how it implements the methods of a superclass or interface? So it's really an anonymous class, not an anonymous instance (or rather, it's no more anonymous than any other object-oriented instance, which typically don't have names inherently, only variable names storing references to them).
It doesn't really make sense to do that with Haskell type classes/instances. The reason is that a Haskell instance represents something very different from an OO instance.
The instances of OO classes are objects (even the instances of interfaces are objects). All of a class' methods will always be invoked on an instance of that class. So it makes sense to create an anonymous subclass of an existing class or interface at the time you create a new object. You basically say how that object implements the required methods, as an alternative to declaring a whole named class of objects that implement the methods the same way, which you could instantiate in multiple places.
The instances of Haskell classes are types (which is why the're called type classes). All of the methods of a class must involve the type somehow, but there is no guarantee that they take an input of the type. For example, consider the class1:
class Monoid' a
where mempty' :: a
mappend' :: a -> a -> a
It doesn't really make sense to say an object is an instance of Monoid'; if I were to create a new object and I wanted to anonymously instantiate Monoid', how would I define mempty'? mempty' isn't an operation I could invoke on my new object, it's an operation that receives no inputs at all (not even an implicit "this") and produces a value2.
And then there's things like:
class Functor' f
where fmap :: (a -> b) -> (f a -> f b)
Nothing ever takes an input of a type f that is an instance of Functor'; it doesn't even make sense to talk about something that might, since the instances of the class Functor' are type constructors that need a type parameter to result in a type, not types that actually contain values. So again, it just makes no sense at the point that I'm creating a new object to say "and here's how this object implements Functor'").
It could potentially make sense to declare a new anonymous type locally, and declare how it implements some type classes at the same time. But Haskell has no syntax for it, no.
Fortunately, you also don't need to create anonymous classes/instances in order to have a one-off collection of functions that conforms to a known interface. Functions are first-class values too, so you can just have type whose fields are functions. Then anywhere you like you can create a new value of that type by providing a definition for all of the function fields. For example:
data MyInterface = MyInterface
{ foo :: Int -> Bool
, bar :: Int -> String
}
example :: MyInterface -> Int -> (Bool, String)
example impl x
= (foo impl x, bar impl x)
main = do
let impl = MyInterface { foo = even, bar = show }
print $ example impl 7
The above program prints (False,"7").
1 I'm using Monoid' rather than Monoid (and similarly Functor') because I'm using simplifications of the real classes. You can see the real definition with :info Monoid in ghci (or look up the documentation) if you're interested.
2 Or alternatively, the class Monoid' mandates that there simply exists a value of each type that instantiates it, and mempty' just is a reference to it.
I have a concept like this:
type Foo = concept x, y
x.test(y) is bool
And then a type that tries to define a method that implements the concept:
type Bar = object
s: string
proc test(x: Bar, y: string): bool =
x.s == y
And a type that has a generic field T: Foo with a constructor that receives a T: Foo:
type Baz[T: Foo] = object
f: T
proc make[T: Foo](f: T): auto =
result = Baz[T](f: f)
When I create a new Bar and pass it to the make proc to make a new Baz, it doesn't compile:
let bar = Bar(s: "whatever")
let made = make[Bar](bar)
Error: type mismatch: got (Bar) but expected 'T'
However it compiles if I drop the y in the concept, like x.test is bool and update the test proc accordingly.
What am I doing wrong?
Change
type Foo = concept x, y
x.test(y) is bool
To
type Foo = concept x
x.test(string) is bool
In your code, it means x and y are both Foo type. If you really means that, please try this.
proc test(x: Bar, y: Bar): bool =
x.s == y.s
Many functional programming languages have support for curried parameters.
To support currying functions the parameters to the function are essentially a tuple where the last parameter can be omitted making a new function requiring a smaller tuple.
I'm thinking of designing a language that always uses records (aka named parameters) for function parameters.
Thus simple math functions in my make believe language would be:
add { left : num, right : num } = ...
minus { left : num, right : num } = ..
You can pass in any record to those functions so long as they have those two named parameters (they can have more just "left" and "right").
If they have only one of the named parameter it creates a new function:
minus5 :: { left : num } -> num
minus5 = minus { right : 5 }
I borrow some of haskell's notation for above.
Has any one seen a language that does this?
OCaml has named parameters and currying is automatic (though sometimes type annotation is required when dealing with optional parameters), but they are not tupled :
Objective Caml version 3.11.2
# let f ~x ~y = x + y;;
val f : x:int -> y:int -> int = <fun>
# f ~y:5;;
- : x:int -> int = <fun>
# let g = f ~y:5;;
val g : x:int -> int = <fun>
# g ~x:3;;
- : int = 8
Sure, Mathematica can do that sort of thing.