这是场景:我已经编写了一些带有类型签名的代码,并且GHC抱怨无法推断x~y某些x和y.你通常可以将GHC作为一个骨骼并简单地将同构函数添加到函数约束中,但这有几个原因:
我只花了几个小时与案例3作斗争.我正在玩syntactic-2.0,我试图定义一个与域无关的版本share,类似于在中定义的版本NanoFeldspar.hs.
我有这个:
{-# LANGUAGE GADTs, FlexibleContexts, TypeOperators #-}
import Data.Syntactic
-- Based on NanoFeldspar.hs
data Let a where
Let :: Let (a :-> (a -> b) :-> Full b)
share :: (Let :<: sup,
Domain a ~ sup,
Domain b ~ sup,
SyntacticN (a -> (a -> b) -> b) fi)
=> a -> (a -> b) -> a
share = sugarSym Let
Run Code Online (Sandbox Code Playgroud)
和GHC could not …
代码
{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
-- I know this particular example is silly.
-- But that's not the point here.
g :: forall a . RealFloat a => Bool
g = True
main :: IO ()
main = print (g @Double)
Run Code Online (Sandbox Code Playgroud)
无法在GHC 8.0上编译并出现错误
• Could not deduce (RealFloat a0)
from the context: RealFloat a
bound by the type signature for:
g :: RealFloat a => Bool
at app/Main.hs:3:6-35
The type variable ‘a0’ is ambiguous
• In the ambiguity check …Run Code Online (Sandbox Code Playgroud) 我用GHC 7.8做了相当有趣的事情,但是遇到了一些问题.我有以下内容:
mkResultF :: Eq k => Query kvs ('KV k v) -> k -> ResultF (Reverse kvs) (Maybe v)
mkResultF Here key = ResultComp (pure . lookup key)
mkResultF q@(There p) key =
case mkResultF p key of
ResultFId a -> pure a
ResultComp c ->
ResultComp $ \foo ->
case c foo of
ResultFId a -> pure a
ResultComp c ->
ResultComp $ \foo ->
case c foo of
ResultFId a -> pure a
Run Code Online (Sandbox Code Playgroud)
很明显,这里有一些东西需要抽象,但我不知道如何去做.当我尝试以下内容时:
mkResultF :: Eq …Run Code Online (Sandbox Code Playgroud) 我最近发现了Data.Promotion一半的单身人士.它具有大量类型系列,允许在类型级别进行基本上任意计算.我有几个关于用法的问题:
是什么区别($),(%$),($$),和他们在有关:++$,:.$等等?这些实际上是中缀运营商吗?我的印象是所有中缀类型的构造函数都必须以a开头:.
我正在尝试在列表上映射构造函数:
{-# LANGUAGE DataKinds, TypeOperators, PolyKinds #-}
import Data.Promotion.Prelude
data Foo a b
type MyList = '[Int, Double, Float]
-- expects one more argument to `Foo`
type FooList1 b = Map ((Flip Foo) $ b) MyList
-- parse error on the second `b`
type FooList2 b = Map (($ b) :. Foo) MyList
Run Code Online (Sandbox Code Playgroud)
但是我在使用多参数类型构造函数时遇到了麻烦.想法?
我可以用以下函数替换我用等效函数编写的所有类型函数Data.Promotion:
type family ListToConstraint …Run Code Online (Sandbox Code Playgroud)我最近发现-XTypeApplications,它允许我写缩写我的代码.考虑以下:
{-# LANGUAGE AllowAmbiguousTypes, DataKinds, KindSignatures, RankNTypes,
ScopedTypeVariables, TypeApplications #-}
import Data.Tagged
import Data.Proxy
class Foo (a :: Bool) where
foo :: Tagged a Int
instance Foo 'True where
foo = 3
instance Foo 'False where
foo = 4
Run Code Online (Sandbox Code Playgroud)
而不是写作proxy foo (Proxy::Proxy 'True),我现在可以写untag $ foo @'True,这节省了很多Proxy样板.没关系,但我们可以用模糊的类型做得更好:
foo' :: forall (a :: Bool) . (Foo a) => Int
foo' = untag $ foo @a
Run Code Online (Sandbox Code Playgroud)
现在我可以写了foo' @'True!请注意,尽管之前类型不明确-XTypeApplications,但我不再指定类型了a.我认为这很好,但其他人可能不会.所以我希望引入一个包装器 …
以下编译没有 PolyKinds:
{-# LANGUAGE TypeFamilies, GADTs #-}
type family Modulus zq
type family Foo zq q
data Bar :: (* -> *) where
Bar :: (zq' ~ Foo zq (Modulus zq)) => Bar (zq -> zq')
Run Code Online (Sandbox Code Playgroud)
所有外观zq都是某种类型(种类*)代表模数运算模型q.用它Nats来表示这些模量很方便.如果我PolyKinds在类型族中添加和多样化模数:
{-# LANGUAGE TypeFamilies, GADTs, PolyKinds #-}
type family Modulus zq :: k
type family Foo zq (q :: k)
data Bar :: (* -> *) where
Bar :: (zq' ~ Foo …Run Code Online (Sandbox Code Playgroud)