强制对参数进行参数化

时间:2020-05-25 19:45:20

标签: haskell parametric-polymorphism

使用RankNTypes可以强制执行各种参数。例如,A id :: A

newtype A = A { unA :: forall a. a -> a }

但是,当我们关心函数的参数参量时,情况又如何呢?对于特定情况,以下方法将起作用:

newtype X b = X { unX :: forall a. a -> (a, b) }

例如X (\a -> (a, ())) :: X ()

我想了解如何(或是否可以)构造参数测试,该测试对于\a -> (a, f a)形式的函数更普遍,其中f可以是常数(如上)或可能参数本身。 X无法完成此操作。例如X (\a -> (a, id a))是类型错误。能做到吗?

编辑:我想在这个问题上稍作休息或阐述。假设我们有一种参数化状态转换器:

type PState i o a = i -> (a, o)

还假设我们对静态强制任意a中的m :: PState i o a不以任何方式依赖i感兴趣。换句话说,是否可以定义一个函数f,以便在f m的值不依赖于输入的情况下正确键入m(在这种情况下,其结果为{ {1}}),否则输入不正确吗?

1 个答案:

答案 0 :(得分:1)

您需要创建一个显式的类型级函数来完成此操作。通常假定通常量化的Type -> Type变量是类型构造函数(内射函数),在此还不够。但是也可能有非内射类,它们被称为类型 families 。不利的一面是您需要一些单独的索引所需的方法,因为如果没有这种方法,类型推断将无法工作。

{-# LANGUAGE TypeFamilies, KindSignatures, EmptyDataDecls, TypeInType
           , RankNTypes, UnicodeSyntax #-}

import Data.Kind

type family MyTyFun (f :: Type) (a :: Type) :: Type

newtype GState f = GState { unGS :: ∀ a . a -> (a, MyTyFun f a) }

data Af
type instance MyTyFun Af a = ()
type A = GState Af

data Xf b
type instance MyTyFun (Xf b) a = b
type X b = GState (Xf b)

data Wf
type instance MyTyFun Wf a = a
type W = GState Wf
> unGS (GState (\a -> (a, a)) :: W) 4
(4,4)