使用堆栈与lts-9.2(和单例-2.1),我有这个:
$(singletons [d|
data EventScans
= PassThrough
| SuiteProgress
-- cn :: EventScans -> [Char]
cn PassThrough = "all-events"
cn SuiteProgress = "suite-progress"
|])
我不能给这个函数一个类型签名,推断的类型签名是cn :: IsString t => EventScans -> t
。 AFAIK IsString
不会单一化。
如果没有cn
上的类型签名,我会按预期获得Cn
类型系列。如果我尝试添加类型签名,我会得到:
* Expected kind `[Char]', but `"all-events"' has kind `Symbol'
* In the type `"all-events"'
In the type family declaration for `Cn' (haskell-stack-ghc)
这样做的正确方法是什么?
修改如果我尝试添加类型签名cn :: IsString t => EventScans -> t
,我会收到以下错误:
Variable `a_agPb' used as both a kind and a type
Did you intend to use TypeInType? (haskell-stack-ghc)
Not in scope: type constructor or class `SIsString'
Perhaps you meant `IsString' (imported from Data.String) (haskell-stack-ghc)
答案 0 :(得分:0)
从我在github上打开的相关问题来看,这是因为mappedBy
还没有单一化。有关详细信息,请参阅https://github.com/goldfirere/singletons/issues/267。
答案 1 :(得分:0)
您需要通过执行以下操作来禁用OverloadedString,或者需要明确其类型:
$(singletons [d|
data EventScans
= PassThrough
| SuiteProgress
-- cn :: EventScans -> [Char]
cn PassThrough = ("all-events" :: String)
cn SuiteProgress = ("suite-progress" :: String)
|])
我认为它不想这样做,因为现在您需要2层多态性(值和类型级别)。我怀疑您是否需要它,所以要明确一点。
但是您在这里所做的事情实际上并不需要单例。 单例仅是从值到类型的必要条件,在这种情况下,您知道所有值,因此可以返回到普通的类型家族:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
module Main where
import Data.Proxy
import GHC.TypeLits
test1 :: String
test1 = getStat $ Proxy @PassTrough
test2 :: String
test2 = getStat $ Proxy @SuiteProgress
data PassTrough
data SuiteProgress
type family Cn d :: Symbol where
Cn PassTrough = "all-events"
Cn SuiteProgress = "suite-progress"
getStat :: forall a b . ((Cn a) ~ b, KnownSymbol b) => Proxy a -> String
getStat _ = symbolVal $ Proxy @b