Haskell中索引约束的处理

时间:2018-12-20 13:19:12

标签: haskell constraints

是否可以在Haskell中对索引约束进行逐点关联?

{-# LANGUAGE KindSignatures           #-}
{-# LANGUAGE RankNTypes           #-}
{-# LANGUAGE DataKinds        #-}
{-# LANGUAGE MultiParamTypeClasses        #-}
{-# LANGUAGE GADTs        #-}
{-# LANGUAGE TypeApplications        #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators        #-}
{-# LANGUAGE ConstraintKinds        #-}


import Data.Kind


class Paramed t where
   type Cxt0 t :: Constraint
   type Cxt2 t :: (* -> *) -> Constraint

data And a b

instance (Paramed a, Paramed b) => Paramed (And a b) where
   type Cxt0 (And a b) = (Cxt0 a, Cxt0 b) -- OK
   --type Cxt2 (And a b) = (\@m -> ((Cxt2 a m, Cxt2 b m))) -- does not work
   type Cxt2 (And a b) m = (Cxt2 a m, Cxt2 b m) -- does not work either

它导致以下内容

error:
    • Number of parameters must match family declaration; expected 1
    • In the type instance declaration for ‘Cxt2’
      In the instance declaration for ‘Paramed (And a b)’

1 个答案:

答案 0 :(得分:3)

您可能需要使用命名类,即类似

instance (Paramed a, Paramed b) => Paramed (And a b) where
   type Cxt0 (And a b) = (Cxt0 a, Cxt0 b) -- OK
   type Cxt2 (And a b) = C a b

class (Cxt2 a m, Cxt2 b m) => C a b (m :: * -> *) where
instance (Cxt2 a m, Cxt2 b m) => C a b m where

打开不确定的实例。 (当然,您可以使用C以外的其他名称)

在Haskell中,* -> *这种类型\ t -> [t]不会被data这样的lambda所居住,因为没有类型级别的lambda。我们需要声明一个命名类型(使用newtype* -> *),并使用它来驻留* -> Constraint

类型(* -> *) -> Constraint相似:您需要一个命名类。 与... -> Constraint或任何其他In [41]: time.perf_counter_ns() Out[41]: 10464788941125 In [42]: time.process_time_ns() Out[42]: 22502272000 In [43]: time.time_ns() Out[43]: 1545312118561931000 In [44]: time.monotonic_ns() Out[44]: 10477720411470 In [45]: time.get_clock_info('perf_counter') Out[45]: namespace(adjustable=False, implementation='mach_absolute_time()', monotonic=True, resolution=1e-09) In [46]: time.get_clock_info('process_time') Out[46]: namespace(adjustable=False, implementation='clock_gettime(CLOCK_PROCESS_CPUTIME_ID)', monotonic=True, resolution=1.0000000000000002e-06) In [47]: time.get_clock_info('time') Out[47]: namespace(adjustable=True, implementation='clock_gettime(CLOCK_REALTIME)', monotonic=False, resolution=1.0000000000000002e-06) In [48]: time.get_clock_info('monotonic') Out[48]: namespace(adjustable=False, implementation='mach_absolute_time()', monotonic=True, resolution=1e-09) 类型同上。

如果我没记错的话,则需要使用命名类型/类来使类型推断成为可能。