| 25 | |

| 26 | === Converting types === |

| 27 | |

| 28 | We determine the converted type `t^` of `t` as follows: |

| 29 | {{{ |

| 30 | T^ = T_CC , if T_CC exists |

| 31 | = T , otherwise |

| 32 | a^ = a_CC |

| 33 | (t1 -> t2)^ = t1 -> t2 , if kindOf t1 == # |

| 34 | or kindOf t2 == # |

| 35 | = t1^ :-> t2^, otherwise |

| 36 | (t1 t2)^ = t1^ t2^ |

| 37 | (forall a.t)^ = forall a_CC.t^ |

| 38 | }}} |

| 39 | Here some examples, |

| 40 | {{{ |

| 41 | (Int -> Int)^ = Int :-> Int |

| 42 | (forall a. [a] -> [a])^ = [a] :-> [a] |

| 43 | ([Int -> Int] -> Int)^ = [Int :-> Int] :-> Int |

| 44 | (Int# -> Int# -> Int#)^ = Int# -> Int# -> Int# |

| 45 | ((Int -> Int) -> Int#)^ = (Int -> Int) -> Int# |

| 46 | (Int -> Int -> Int#)^ = Int :-> (Int -> Int#) |

| 47 | }}} |

| 48 | |

| 49 | Why do we use `(t1 -> t2)^ = t1 -> t2` when either argument type is unboxed, instead of producing `t1^ -> t2^`? Because we want to avoid creating conversion constructors (see below) for such types. After all, the conversion constructor `isoArr` for function arrows works only for arrows of kind `*->*->*`. |

| 50 | |

| 51 | |

| 52 | |

179 | | ~~=== Converting type terms ===~~ |

180 | | |

181 | | ~~We determine the converted type `t^` of `t` as follows:~~ |

182 | | ~~{{{~~ |

183 | | ~~T^ = T_CC , if tyConCC T == ConvCC T_CC~~ |

184 | | ~~ = T , otherwise~~ |

185 | | ~~a^ = a_CC~~ |

186 | | ~~(t1 -> t2)^ = t1 -> t2 , if kindOf t1 == #~~ |

187 | | ~~ or kindOf t2 == #~~ |

188 | | ~~ = t1^ :-> t2^, otherwise~~ |

189 | | ~~(t1 t2)^ = t1^ t2^~~ |

190 | | ~~(forall a.t)^ = forall a_CC.t^~~ |

191 | | ~~}}}~~ |

192 | | ~~Here some examples,~~ |

193 | | ~~{{{~~ |

194 | | ~~(Int -> Int)^ = Int :-> Int~~ |

195 | | ~~(forall a. [a] -> [a])^ = [a] :-> [a]~~ |

196 | | ~~([Int -> Int] -> Int)^ = [Int :-> Int] :-> Int~~ |

197 | | ~~(Int# -> Int# -> Int#)^ = Int# -> Int# -> Int#~~ |

198 | | ~~((Int -> Int) -> Int#)^ = (Int -> Int) -> Int#~~ |

199 | | ~~(Int -> Int -> Int#)^ = Int :-> (Int -> Int#)~~ |

200 | | ~~}}}~~ |

201 | | |

202 | | ~~Why do we use `(t1 -> t2)^ = t1 -> t2` when either argument type is unboxed, instead of producing `t1^ -> t2^`? Because we want to avoid creating conversion constructors for such types. After all, the conversion constructor `isoArr` for function arrows works only for arrows of kind `*->*->*`.~~ |

203 | | |