gpt4 book ai didi

haskell - GHC TypeLits 没有值

转载 作者:行者123 更新时间:2023-12-01 07:55:35 25 4
gpt4 key购买 nike

尝试设计一个类型驱动的 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真的没有帮助。有什么办法可以让这个工作吗?

最佳答案

类型同义词(用 type 定义)在类型检查期间替换为其定义。问题是Printer没有引用 s在其定义中,这导致以下约束:

generic :: KnonwSymbol s => IO ()

此类型签名没有 s右侧 =>因此歧义检查失败。它不能真正工作,因为无处指定什么 s应该是你使用的时候。

不幸的是,GHC 在错误消息中表示类型同义词的方式不一致。有时它们会被扩展,有时它们会被保留。具有讽刺意味的是,我认为错误消息的改进使这个特定错误更难追踪:通常,根据您定义的类型表达错误更清晰,但在这里它隐藏了歧义的原因。

您需要的是某种方式来提供不依赖于类型同义词的相关类型级别符号。但首先,您需要启用 ScopedTypeVariables并添加一个 forallgeneric 的签名以确保 s在类型签名和 s 中在 Proxy :: Proxy s是相同的。

有两种可能:
  • Printernewtype并在使用时打开它:
    newtype Printer (s :: Symbol) = Printer { runPrinter :: IO () }

    generic :: forall s. KnownSymbol s => Printer s
    generic = Printer $ putStrLn (symbolVal (Proxy :: Proxy s))

    main = runPrinter generic
  • 传入一个额外的 Proxy论据 generic ,就像 symbolVal :
    concrete :: Printer "foo"
    concrete = generic (Proxy :: Proxy "foo")

    generic :: forall proxy s. KnownSymbol s => proxy s -> IO ()
    generic _ = putStrLn (symbolVal (Proxy :: Proxy s))

    proxy作为类型变量是一个简洁的习惯用法,它让你不依赖于 Data.Proxy并让调用者传入他们想要的任何东西。
  • 关于haskell - GHC TypeLits 没有值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28572071/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com