Skip to content

Higher order function which outputs Option of multiple generics - Cannot instantiate #5647

@mratsim

Description

@mratsim

I am trying to implement unfoldr from Haskell

This test case works fine, please note the Òption[(T, T)]

from options import Option, isSome, get, none, some
proc unfoldr*[T, U](f: proc(items: T): Option[(T, T)], x:U): seq[T] {. inline .}=
    ## Build a sequence from function f: T -> Option(T,T) and a seed of type T
    result = @[]
    var a: U = x
    var b: T
    var fa = f(a)

    while fa.isSome():
        (b, a) = fa.get()
        result.add(b)
        fa = f(a)

proc divmod10(n: int): Option[(int, int)] =
    if n == 0:
        return none((int,int))
    return some(( (n mod 10).int(), n div 10))

proc toDigits*(n: int): seq[int] =
    unfoldr(divmod10,n)

echo toDigits(123456) # @[6, 5, 4, 3, 2, 1]

However unfoldr type signature should be (in Haskell)

unfoldr :: (b -> Maybe (a, b)) -> b -> [a]

Changing it in the code to the following gives me an error:

proc unfoldr*[T, U](f: proc(items: T): Option[(T, U)], x:U): seq[T] {. inline .}=
unfold.nim(4, 46) Error: cannot instantiate Option
got: ((typedesc[T], U))
but expected: (T)

From the error, I would guess that in the second case the whole Option[(T, U)] got matched by T instead of being unpacked

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions