【发布时间】:2015-02-17 22:10:26
【问题描述】:
尝试设计一个类型驱动的 API,我一直在尝试获得类似以下的工作(使用更复杂的代码/尝试,这被精简到澄清我在寻找什么所需的最低限度) :
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
module Main where
import Data.Proxy
import GHC.TypeLits
type Printer (s :: Symbol) = IO ()
concrete :: Printer "foo"
concrete = generic
generic :: KnownSymbol s => Printer s
generic = putStrLn (symbolVal (Proxy :: Proxy s))
main :: IO ()
main = concrete
这个程序会打印 'foo',但不会:
Could not deduce (KnownSymbol s0)
arising from the ambiguity check for ‘generic’
from the context (KnownSymbol s)
bound by the type signature for
generic :: KnownSymbol s => Printer s
at test5.hs:14:12-37
The type variable ‘s0’ is ambiguous
In the ambiguity check for:
forall (s :: Symbol). KnownSymbol s => Printer s
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature for ‘generic’:
generic :: KnownSymbol s => Printer s
启用AllowAmbiguousTypes 并没有真正的帮助。有什么办法可以让它工作吗?
【问题讨论】:
-
您应该在通话现场为混凝土提供参数吗?
-
@PeterK 有可能,是的,但我看不出这有什么改变?
-
Printer "foo"与Printer "bar"的类型完全相同,因为两者都是IO ()的类型同义词,因此这在当前形式下永远无法工作。