I started using implicit parameters the way you would use reader monad. There are a lot of benefits to this approach: not having to deal with multiple monads. Implicit parameters has all of the benefits of Has pattern without any of the cruft. Honestly I'm not seeing any downside.
@Asad Saeeduddin
I don't think "common" haskell programming does this very often - anything without fancy type classes/type families should be fine, no?
you can't reason about Foo, it's just a made up typeclass with no rules. my point is in contravariant position the type of arguments is not always determined: you often have to fix it using type annotations or visible type applications
if we only ever did things like test :: Foo Int Int => Int -> Int; test = foo, then everything would be fine, but we often apply functions to polymorphic arguments where the input type doesn't wholly determine the result type, and so we need to fix the argument type manually in order to resolve the right instance
@TheMatten this example seems very contrived, and if I have to choose between this complexity, and the complexities that arise from the reader monad I choose this.
@Georgi Lyubenov // googleson78 I think the bar for fancy/complicated is a bit too low then. If you try to model something like a class for vector spaces, like so:
class ... => VectorSpace s v
where
scale :: s -> v -> v
you will have to annotate/visibly type apply the scalar type if you use a numeric literal so as to choose the right instance. this is not a very exotic use case IMO
From this perspective, something like Agda's open on records seems to be superior to instance resolution in terms of clarity, even if it's more verbose
@Julian KG I would say adding type signature is actually something you may do pretty often when working with highly-polymorphic sub-bindings (e.g. in where)
@TheMatten I have an idea for a language with better support for implicit parameters in my head because there have been some things that I think could be more ergonomic. I'll have to read this paper and try out Agda so I see what else is out there.
these are problems with implicit parameters as a language extension, no? my read was that oleg's typeclass-based implicit parameter passing implementation doesn't suffer these drawbacks
I started using implicit parameters the way you would use reader monad. There are a lot of benefits to this approach: not having to deal with multiple monads. Implicit parameters has all of the benefits of Has pattern without any of the cruft. Honestly I'm not seeing any downside.
http://okmij.org/ftp/Haskell/tr-15-04.pdf
I can't open the links to the supposed problems with them
referenced in "the reflection paper"
2020-07-19-125852_483x193_scrot.png
from section 6.2
It think problems boil down to examples like this:
It may not be apparent at first sight which "instance" should be chosen
(It makes a lot of sense from typechecker perspective, but may be hard to spot for human)
oh man that's horrifying tbh
when you realise what's wrong..
I can't remember the last time I wrote a Haskell library/program where this wasn't the case, and I never use implicit parameters
@Asad Saeeduddin
I don't think "common" haskell programming does this very often - anything without fancy type classes/type families should be fine, no?
It's not that much of a problem with "normal classes", because they are globally coherent (usually)
well what's a fancy typeclass? e.g. is this fancy?
In my opinion, it is. I have no idea how to reason about anything like
foo :: Foo a b => a -> b
This does indeed remind me of an annoying "everyday" example though - aeson's FromJSON typeclasses, which has a polymorphic return type
you can't reason about
Foo
, it's just a made up typeclass with no rules. my point is in contravariant position the type of arguments is not always determined: you often have to fix it using type annotations or visible type applicationsif we only ever did things like
test :: Foo Int Int => Int -> Int; test = foo
, then everything would be fine, but we often apply functions to polymorphic arguments where the input type doesn't wholly determine the result type, and so we need to fix the argument type manually in order to resolve the right instancemy point is that
Foo
is indeed complicated from my pov, exactly because it has an entirely polymorphic argument/return-typetypeclasses like that lead to subtle errors, or at least I've made such mistakes with e.g.
FromJSON
@TheMatten this example seems very contrived, and if I have to choose between this complexity, and the complexities that arise from the reader monad I choose this.
@Georgi Lyubenov // googleson78 I think the bar for fancy/complicated is a bit too low then. If you try to model something like a class for vector spaces, like so:
you will have to annotate/visibly type apply the scalar type if you use a numeric literal so as to choose the right instance. this is not a very exotic use case IMO
From this perspective, something like Agda's
open
on records seems to be superior to instance resolution in terms of clarity, even if it's more verbose@Julian KG I would say adding type signature is actually something you may do pretty often when working with highly-polymorphic sub-bindings (e.g. in
where
)@TheMatten I have an idea for a language with better support for implicit parameters in my head because there have been some things that I think could be more ergonomic. I'll have to read this paper and try out Agda so I see what else is out there.
@TheMatten
the code example that went like this:
in the paper is exactly what I'd like to avoid. I think there is a way to achieve monomorphism without adding these
M
's ors ->
's.it might not work as a Haskell extension, and it definitely wouldn't be as powerful as implicit parameters
Georgi Lyubenov // googleson78 said:
these are problems with implicit parameters as a language extension, no? my read was that oleg's typeclass-based implicit parameter passing implementation doesn't suffer these drawbacks
@Will yeah the typeclass based approach does not have those problems, but it does create lots and lots of boilerplate and thus encourages sparing use.