Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem finding implicits for HNil.type #78

Closed
EECOLOR opened this issue Feb 11, 2014 · 8 comments
Closed

Problem finding implicits for HNil.type #78

EECOLOR opened this issue Feb 11, 2014 · 8 comments

Comments

@EECOLOR
Copy link

EECOLOR commented Feb 11, 2014

For quite some time I had a problem using maps and folds. I finally figured out it was because it could not find implicits that involve Int.type.

object test extends Poly1 {
  implicit def caseAll[O] = at[O] { entry => entry }
}

HNil.map(test)

Causes the following error:

could not find implicit value for parameter mapper: shapeless.ops.hlist.Mapper[test.type,shapeless.HNil.type]

Changing the call of map to the following solves the problem:

(HNil:HNil).map(test)

Another workaround is to define an implicit for HNil.type:

implicit val hnil =
  new Mapper[test.type, HNil.type] {
    type Out = HNil.type
    def apply(l: HNil.type): Out = HNil
  }

It's very hard to notice this error because most implicits involving HList depend on the HNil implicits.

Not sure how this would be fixed. The result of a fold on an HNil becomes useless:

val one = true :: HNil
val two = one.foldRight(HNil)(test)
two.foldRight(HNil)(test)

The above code gives the following error:

could not find implicit value for parameter folder: shapeless.ops.hlist.RightFolder[shapeless.::[Boolean,shapeless.HNil.type],shapeless.HNil.type,test.NestedValidation.test.type]

It can be solved by calling foldRight like this:

  one.foldRight(HNil:HNil)(test)
@EECOLOR
Copy link
Author

EECOLOR commented Feb 11, 2014

Note that the HList.apply() method also return HNil.type

@milessabin
Copy link
Owner

Sorry it's taken me so long to get respond on this ...

I think this is unfortunate, but ultimately the correct behaviour: what you're observing is the compiler distinguishing between the type HNil and the singleton type of the HNil object HNil.type, and is closely related to the common Scala problem with overly precise types being inferred for Nil, None, Some etc. In shapeless's case it's complicated by the fact that we do often want very precise types inferred and propagated, so a "widen by default" policy a la Scalaz (see some, none etc.) is also problematic.

I'm open to other suggestions, but for now I think I would classify this as not a bug, but a candidate for improved documentation. PRs in that vein would be very welcome.

@EECOLOR
Copy link
Author

EECOLOR commented Jun 24, 2014

No problem.

The HList.apply() problem can be easily fixed by setting the return type to HNil.

The HNil problem might be solved by changing HNil from an object to a val in the package object.

If I'm not mistaken there is no need for the existence of HNil.type (the object).

@milessabin
Copy link
Owner

Could you give those ideas a try and send a PR my way?

@EECOLOR
Copy link
Author

EECOLOR commented Jul 2, 2014

I did not realize that compiling the library is so CPU intensive.

Anyway, there seems to be a problem in the compiler. When I move the HList and it's sub classes into the package object it trips.

Part of this can be fixed by changing

package shapeless
package syntax

Into

package shapeless.syntax

import shapeless._

On changing the object definition to a val I get match may not be exhaustive messages, this is weird as pattern matching should also work on vals that start with an upper case letter.

My knowledge about the library is too limited to determine if this is actually caused by a wrong definition in the tests (brought up by having correct compiler behavior) or a bug in the compiler. It feels that the compiler is at least not consistent in handing stuff in packages v.s. package objects.

Adding :HNil has no effects on the tests and could easily be added.

@milessabin
Copy link
Owner

Do you have a branch I could take a look at?

@EECOLOR
Copy link
Author

EECOLOR commented Aug 4, 2014

I'm sorry for the late reaction. Because it didn't work I removed the code.

@milessabin
Copy link
Owner

OK, thanks ... I'm going to close this issue for now. Feel free to reopen if you'd like to pursue it further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants