Ako môžem odvodiť typeclass príkladov z obmedzenia rodín, ktoré sú v pôsobnosti?

0

Otázka

edit: som nadviazala s viac konkrétnu otázku. Ďakujeme, že ste answerers tu, a ja si myslím, ale otázka sa lepšie vysvetliť zmätky, zoznámil som tu.


TL;DR som snažia získať dôkazy o obmedzení do výrazov, pri používaní pridávať nové aplikácie s existenciálne obmedzenia na konštruktérov. (to je vážne sústo,, prepáč!)


Som destilovanej problém sa dole na nasledujúce. Som jednoduchý GADT, ktorý predstavuje bodov názvom X a funkcie aplikácie s názvom F. Body X sú fixovaný, aby sa Objects.

data GADT ix a where
  X :: Object ix a => a -> GADT ix a
  F :: (a -> b) -> GADT ix a -> GADT ix b

Constrained týka kontajnerov, ktorých objekty sú obmedzené tým, že niečo a Object je to niečo. (edit: môj skutočný problém zahŕňa Category a Cartesian žiaci z obmedzená-kategórie)

-- | I can constrain the values within containers of kind `* -> *`
class Constrained (ix :: * -> *) where
  type Object ix a :: Constraint

-- | Here's a trivial constraint. A more interesting one might include `Typeable a`, for ex
instance Constrained (GADT ix) where
  type Object (GADT ix) a = (Constrained ix, Object ix a)

Ja by som chcel napísať výraz:

-- error: Could not deduce: Object ix Int arising from a use of ‘X’
ex0 :: GADT ix String
ex0 = F show (X (3 :: Int))

A zatiaľ čo zrejmé, riešenie funguje to rýchlo stáva podrobného pri stavbe väčších výrazy:

-- Typechecks, but eventually verbose
ex1 :: Object ix Int => GADT ix String
ex1 = F show (X (3 :: Int))

Myslím, že správne riešenie by malo vyzerať približne takto:

-- error: Could not deduce: Object ix Int arising from a use of ‘X’
ex2 :: Constrained ix => GADT ix String
ex2 = F show (X (3 :: Int))

Ale stále nemôžem dostať, že dôkaz Object ix Int.

Som si istý, že je to jednoduchšie, ako si myslím. Snažil som sa pridať obmedzenia na Object obmedzenia rodiny v GADT trieda stupňa. Snažil som sa ponúka obmedzenia vo výraze podpis. Snažil som sa QuantifiedConstraintsaj napriek tomu , že nie som si istý, že som plne pochopiť ju ešte. Prosím, pomôžte mi múdry ty!


Runnable:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE InstanceSigs #-}

module Test where

import Data.Kind
import Data.Functor.Identity
import Data.Functor.Const

-- | I can constrain the values within containers of kind `* -> *`
class Constrained (ix :: * -> *) where
  type Object ix a :: Constraint

-- | Here's a trivial constraint. A more interesting one might include `Typeable a`, for instance
instance Constrained (GADT ix) where
  type Object (GADT ix) a = (Constrained ix, Object ix a)

-- | A demo GADT that has function application ('F'), and points ('X'). The
-- points are constrained.
data GADT ix a where
  X :: Object ix a => a -> GADT ix a
  F :: (a -> b) -> GADT ix a -> GADT ix b

-- -- Broken
-- -- error: Could not deduce: Object ix Int arising from a use of ‘X’
-- ex0 :: GADT ix String
-- ex0 = F show (X (3 :: Int))

-- Typechecks
-- but for larger programs becomes verbose, requiring many explicit constraints
ex1 :: Object ix Int => GADT ix String
ex1 = F show (X (3 :: Int))

-- -- What I want, but, it's broken
-- ex2 :: Constrained ix => GADT ix String
-- ex2 = F show (X (3 :: Int))
2

Najlepšiu odpoveď

1

Bez toho viac kontexte je ťažké povedať, čo je najlepšie riešenie, ale tu je niekoľko možností:

Vyhnúť obmedzujúca na všetkých

Ako to stojí, vaše GADT nezdá sa, že oveľa dôvod pre obmedzenie X na Object. Možno je to jednoducho nie je potrebné?

data GADT ix a where
  X :: a -> GADT ix a
  F :: (a -> b) -> GADT ix a -> GADT ix b

Namiesto toho, obmedzenia by mohli prísť z vonku , keď je to potrebné.

Bite the bullet obmedzenia zoznamy, ale aby ich krajší

Ak máte mnoho rôznych typov v výraz, ktorý všetky potrebné splniť isté obmedzenia, môžete použiť pomocné ako All

ex2' :: All (Object ix) '[Int] => GADT ix String
ex2' = F show (X (3 :: Int))

tam, kde môže byť viac typov v zozname okrem Int; a/alebo si môžete urobiť synonymum obmedzenia, ako napríklad

type StdObjs ix = (Object ix Int, Object x Bool, ...)

ex2'' :: StdObjs ix => GADT ix String
ex2'' = F show (X (3 :: Int))

Propagácia obmedzenia dozadu cez štruktúru dát sám

Ak potrebujete obmedzenia na X hodnoty, môže byť napriek tomu možné vyjadriť túto iným spôsobom v GADT. Napríklad, ak je táto funkcia nie je všeobecný funkciu, ale niečo, čo už je fixovaný na akceptovať len Objects, mohli by ste mať to, ako je tento:

data YourFunc ix a b where
  YourFunc :: Object ix a => (a->b) -> YourFunc ix a b

show' :: Object ix Int => YourFunc ix Int String
show' = YourFunc show

To nebude priamo pomôcť s problémom, že ste boli dotazovaní, ale možno je funkcia zdieľané alebo niečo. Mohli by ste dokonca niečo ako

class Object ix a => InferrenceChain ix a where
  type PreElem ix a :: Type
  propInferrence :: (InferrenceChain ix (PreElem a) => r) -> r

a potom

data YourFunc ix a b where
  YourFunc :: InferrenceChain ix a
                 => (PreElem a -> a) -> YourFunc (PreElem a) a

Potom na konci by ste mohli dôkaz X obmedzenia len z uvedenie do Object ix String na vonkajšej a recursing viac propInferrence. Ale to by asi si docela nešikovný.

2021-11-23 18:30:17

Ja som sa pýtal sledovať otázku. Wrt eliding obmedzenia, následné ukazuje, prečo ich potrebujem. Wrt obmedzenia zoznam, stále si myslím, štandardný by sa stal insufferably veľké. Wrt YourFunc, že by zaviesť tony dopredu kotla doska (nový predohra), aj keď, asi eliminovať budúce štandardný. Wrt InferrenceChainSom snaží mapa je na môj problém, ale možno, ale pomáha lepšie vysvetliť? Ďakujem btw!
Josh.F

woh, len som si uvedomil, ste autor knižnice som pohrávate s, constrained-categoriesvďaka knižnici, je to úžasné!
Josh.F

Dobre, som rád, počuť ho nájdete užitočné!
leftaroundabout
1

Myslím, že správne riešenie by malo vyzerať približne takto:

-- error: Could not deduce: Object ix Int >arising from a use of ‘X’
ex2 :: Constrained ix => GADT ix String
ex2 = F show (X 3)

Bohužiaľ, toto riešenie nedáva žiaden zmysel. Kompilátor je odôvodnené poukazuje na to, že to nevie, že Object ix Int je spokojný v tomto bode, keďže všetko vie, je to, že Constrained ix môže uložiť niektoré obmedzenia prostredníctvom Object ix Int.

Riešenie prostredníctvom kvantifikácie

Tak snáď to, čo chcete, je obmedzenie, ktoré hovorí: "v tomto bode, všetky Object ix a obmedzenia používam sú spokojní", ktoré môžeme vyskúšať a urobiť prostredníctvom kvantifikácie:

{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ConstraintKinds #-}

type Satisfied ix = forall a. Object ix a

ex2 :: Satisfied ix => GADT ix String
ex2 = F show (X 3)

Bohužiaľ, ktoré nám dáva KDE chyba:

• Quantified predicate must have a class or type variable head:
        forall a. Object ix a
• In the quantified constraint ‘forall a. Object ix a’
  In the type synonym declaration for ‘Satisfied’

Od Object je typom rodiny a nie na triedu alebo typ premennej.

Re-architektúra

Ale... prečo je Object typ rodiny? V skutočnosti, prečo Constrained existujú vôbec ako nezákonné triedy s č metódy? Ak chceme uplatňovať obmedzenia na kombináciu obalov a typy, Gnu už nám dáva prostriedky na to stačí použiť stupňa obmedzenia!

{-# LANGUAGE MultiParamTypeClasses #-}

class Object ix a

type Constrained ix = forall a. Object ix a

Pretože, ak sme

instance (...<some stuff>...) => Constrained Foo where
  type Object ix a = (...<some def>...)

by sme mohli preložiť, že

instance (...<some stuff>..., ...<some def>...) 
  => Object ix a

Čo robí tento príklad zostaviť.

ex2 :: Constrained ix => GADT ix String
ex2 :: F show (X 3)
2021-11-23 10:52:50

To dáva zmysel. Bohužiaľ, to, čo som zjednodušené, aby Constrainedmôj skutočný problém, je vlastne Category a Cartesian z cartesian-categories,, ktoré sú oprávnené s metódami. Neviem, spôsob, iné ako TypeFamilies (t. j. tlak rodiny, tu) vyjadriť myšlienku triedy, ktorých objekty sú ľubovoľne obmedzená subtypes z Hask, takže si nemyslím, že rearchitecture bude pracovať pre tento konkrétny problém.
Josh.F

Máte na mysli categories knižnica? Myslím si, že je potrebné poskytnúť viac motivačný príklad, prečo liečbe Object ako trieda nefunguje ako prístup, pretože to nie je mi jasné od pohľade na tieto triedy.
Isaac van Bakel

Josh.F

Josh.F

Vaše príklady veľmi klesať rovnako cesty som šiel. Wrt váš nápad rearchitecture to, čo som sa pýtal sledovať otázku, ktorá ukazuje, prečo nemôžem, a to Object je typefamily, že prekážok co/domény a je požiadavka z inej knižnice.
Josh.F

V iných jazykoch

Táto stránka je v iných jazykoch

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................