5 ms·
To me, type-classes are used like a less flexible form of duck typing. I would really like to see a more flexible strongly typed duck-typing than type-classes.
by timthelion 9y ago
To me, type-classes are used like a less flexible form of duck typing. I would really like to see a more flexible strongly typed duck-typing than type-classes. I think that a sufficiently advanced IDE could auto-generate, from an expression, a "duck-type" for each untyped object used. For example, if you have the expression:
(given) g :: Int -> String
function a =
let
l = (f a)
in
g l
Would it be possible to generate the duct-type
"function :: (a which has a method f :: a -> Int) -> String"
Now you're not saying that a has to belong to a typeclass, you are saying that a has a duck-type of any value with a method f :: a -> Int.
- catnaroek 9y agoFine. Now propose a concrete type-checking algorithm. And make it scalable.
- wtetzner 9y agoI think row types are probably what OP is looking for. And they can be fully inferred.
- catnaroek 9y agoI don't think row polymorphism is what the OP asked for. They might be what the OP wants, but that's a-whole-nother matter. If I understood correctly, the OP asked for a “duck type of all values on which a function `f` can be applied”. Alas, OCaml-like object types are glorified function types, not duck types: (0) The type of an object is the type of its methods. (1) The type of an object is not the type of its internal state. Say you have a particular data type like `float list`, and you want to “bless it with a method `f`”, so that you can pass a `float list` to any context that expects an object with a method `f`. This is everyday stuff in duck-typed languages. Turns out, you can't. The best thing you can do is explicitly construct an object with a method `f`, and whose state happens to be a `float list`. Alas, because the state isn't a part of the object's type, there is no way a user of the object can recover the original `float list`. In fact, no user of the object has any way to tell whether the object's internal state is a `float list` or something else altogether.
- wtetzner 9y ago> I don't think row polymorphism is what the OP asked for. They might be what the OP wants, but that's a-whole-nother matter. I think that's the other way around. It appears to be what they asked for, even if it may not be what they want. They pretty clearly said they wanted to be able to write a type that says "Object that has method f :: a -> Int". What you're talking about doesn't seem to be duck typing (though it might work nicely along side duck typing), it's being able to add methods to objects at run time (unless I'm misunderstanding).
- default-kramer 9y agoI think OCaml does what you are looking for. See the example on https://en.wikipedia.org/wiki/Structural_type_system https://en.wikipedia.org/wiki/Structural_type_system, which features OCaml.
- timthelion 9y agoThanks, looks interesting. One of the things I've always wondered about with this approach is, how do you then show the "duck type"s in a succinct and human readable way. This is pretty succinct, but I'd have to say that it is not obvious what the syntax means: val y : < get_x : int; set_x : int -> unit > = <obj> Perhaps the example was poorly chosen, what is "unit"?
- deciduously 9y agoIt's () in haskell. Here's a good write-up: https://stackoverflow.com/a/16893900 https://stackoverflow.com/a/16893900
- wtetzner 9y agoUnit is a type that has exactly one value, (). It's often used like `void` is used in C-like languages. So this: val y : < get_x : int; set_x : int -> unit > means an object that has a get_x method that returns an int, and a set_x method that takes an int and returns unit (void).