2

Does a Int => Option[Nat] function exist in Shapeless?

Its type signature:

intToOptionNat(a: Int): Option[Nat] = ???

Examples:

intToOptionNat(5)   == Some( Nat(5) )
intToOptionNat(-42) == None
manojlds
  • 290,304
  • 63
  • 469
  • 417
Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384
  • Not 100% on this; this function does not exist in shapeless. You can use Nat.apply to create a function which does this. – Marcus Henry Aug 26 '16 at 12:18
  • `Nat` is a pretty useless type, and if you just want to check for equality you'd be better off going in the other direction. Something like `foo[N <: Nat](a: Int): Option[N]` might be a little more useful, and off the top of my head I don't know whether that exists in Shapeless. – Travis Brown Aug 26 '16 at 18:54
  • Well, I was planning to use this question's answer into http://stackoverflow.com/questions/39156628/enforce-bounded-nat. Let's say I have `case class X(n: N)` where `N` is a `Nat` between 0 and 5, exclusively. – Kevin Meredith Aug 26 '16 at 19:36

1 Answers1

1

I think that what you're looking for is a function which will convert an Int to the corresponding Nat subtype, which will be something of the form _0, Succ[_0], Succ[Succ[_0]] etc.

Because we typically want to exploit the structure of the resulting Nat subtype in some subsequent type level computation this is something which need to know statically, at compile time. Consequently the type Int isn't sufficiently precise ... we need an Int singleton type instead. These are not (yet) directly expressible in Scala, however shapeless provides a macro-based implicit conversion for computing a Nat from an Int literal,

scala> import shapeless.syntax.nat._
import shapeless.syntax.nat._

scala> def intToNat(n: Nat): n.type = n
intToNat: (n: shapeless.Nat)n.type

Since this is computed statically there's no need for the result type to be wrapped in Option ... if the argument literal doesn't have a Nat representation it will be a compile time error,

scala> intToNat(5)
res0: Succ[Succ[Succ[Succ[Succ[_0]]]]] = Succ()

scala> intToNat(-42)
<console>:19: error: Expression -42 does not evaluate to a non-negative Int literal
       intToNat(-42)
                 ^
Miles Sabin
  • 23,015
  • 6
  • 61
  • 95
  • Thanks for answering. Ultimately, I'm trying to create a JSON reader (JSON -> A) for a Nat. So, as I understand, I need to dynamically build a Nat - hence the Option[Nat] return type. – Kevin Meredith Aug 28 '16 at 22:22
  • As @travisbrown observed in a comment on your question the type `Option[Nat]` isn't of any use to you. I suggest you try framing your problem differently. – Miles Sabin Aug 28 '16 at 22:30