Get to type (apply in-parallel lst)


I am trying to type the following function:

(: lists-transpose (All (a) (-> (Listof (Listof a)) (Listof (Listof a)))))
(define (lists-transpose lsts)
  (sequence->list (in-values-sequence (apply in-parallel lst))))

This tells me:

; /home/scolobb/Candies/prj/racket/dds/utils.rkt:456:20: Type Checker: Polymorphic function `in-values-sequence' could not be applied to arguments:
; Argument 1:
;   Expected: (Sequenceof a ... a)
;   Given:    SequenceTop
;   in: (in-values-sequence (apply in-parallel lsts))


> (define lst : (Listof (Listof Symbol)) '((a b) (c d)))
> (apply in-parallel lst)
- : SequenceTop

And casting doesn't work:

> (cast (apply in-parallel lst) (Sequenceof (Listof Symbol)))
; broke its own contract
;   any-wrap/c: Unable to protect opaque value passed as `Any`
;   value: #<sequence>
;   in: Any
;   contract from: typed-world
;   blaming: typed-world
;    (assuming the contract is correct)
;   at: utils.rkt/typed::3821-3880
; Context:
;  /gnu/store/nivzasmjdp2pgh93hj7wvwrlmwkasljh-racket-minimal-8.3/share/racket/collects/racket/repl.rkt:11:26

How do I handle SequenceTop?

How do I type lists-transpose ?


1 Like

How do I type lists-transpose ?

(: lists-transpose (All (a ...) (-> (List (Listof a) ... a) (Listof (List a ... a)))))
(define (lists-transpose lsts)
  (sequence->list (in-values-sequence (apply in-parallel lsts))))
1 Like

Wow, thank you very much @Kalimehtar ! I was re-reading the doc of the type of -> this morning, but I didn't see how I could make it work.

In fact, I thought that ... could only be used between the arguments of the function, and your solution shows that ... is much more powerful than I thought. Awesome! :tada:

I simply write in-parallel in REPL and got:

> in-parallel
- : (All (a ...) (-> (Sequenceof a) ... a (Sequenceof a ... a)))

Then I thought, that Type Checker cannot take finite list of types (a ...) when in (apply in-parallel lst) lst has (Listof ...) type. I tried with (List ..): it works. Then I build correct type like given type of in-parallel.

1 Like

(define transpose (lambda (x) (map list x)))

(transpose '((a b c) (2 3 4)))

1 Like

Thank you @joskoot for your suggestion. Your literal code yields '(((a b c)) ((2 3 4))).

Perhaps you meant something like:

(define lists-transpose ((curry map) list))

This version would work like this: (transpose '(a b c) '(2 3 4)).

The following version will work on a list of lists:

(define (lists-transpose lsts) (apply ((curry map) list) lsts))

However, when I try to type this code, I run into other type errors related to curry, which I am not willing to look at right now :slight_smile:

Thanks anyway: I completely missed the natural approach to transposition by mapping list over multiple lists at the same time!