You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中能否使用语法糖构建存在量化类型的列表?

为什么OverloadedLists无法实现需求

OverloadedLists扩展的脱糖逻辑是先将[a, b, c]转换为标准同构列表a : b : c : [],再调用fromList/fromListN转换为目标类型。标准列表要求所有元素类型完全一致,这一步的类型检查发生在fromList调用之前,所以哪怕你的ShowList支持异质元素,也过不了标准列表的类型校验,这条路是走不通的。

可行的替代方案

你可以通过两种常用方案实现接近原生列表的语法糖:

方案1:可变参数类型类实现

这种方案不需要Template Haskell,靠类型类的多态实现可变参数的构造函数,语法上和普通函数调用接近:
首先开启必要扩展:

{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}

然后定义类型类和实现:

data ShowList = Nil | forall a. Show a => a :* ShowList
infixr 5 :*

-- 可变参数构造类型类
class MkShowList r where
  mkShowList' :: ShowList -> r

instance MkShowList ShowList where
  mkShowList' :: ShowList -> ShowList
  mkShowList' = id

instance (Show a, MkShowList r) => MkShowList (a -> r) where
  mkShowList' :: ShowList -> a -> r
  mkShowList' acc x = mkShowList' (x :* acc)

-- 导出的构造函数,自动补全末尾的Nil
mkShowList :: MkShowList r => r
mkShowList = mkShowList' Nil

使用的时候直接传任意多个Show实例即可:

myShowList :: ShowList
myShowList = mkShowList 'x' () "test" 123

这种方案的缺点是参数之间用空格分隔,不是逗号分隔的列表格式,但不需要额外的Template Haskell扩展。

方案2:Template Haskell准引号实现

如果你一定要用逗号分隔的类列表语法,可以用准引号实现,语法可以做到非常接近你要的效果:
首先开启必要扩展:

{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
import Language.Haskell.TH
import Language.Haskell.TH.Quote

data ShowList = Nil | forall a. Show a => a :* ShowList
infixr 5 :*

然后定义准引号:

showList :: QuasiQuoter
showList = QuasiQuoter
  { quoteExp = \s -> do
      exps <- parseExp s >>= \case
        ListE es -> pure es
        _ -> fail "showList quasiquoter only accepts comma-separated list expressions"
      foldr (\e acc -> [| $e :* $acc |]) [| Nil |] exps
  , quotePat = undefined
  , quoteType = undefined
  , quoteDec = undefined
  }

使用的时候语法如下:

myShowList :: ShowList
myShowList = [showList| 'x', (), "test", 123 |]

这种方案的语法和你想要的原生列表语法非常接近,只需要在列表外面套一层准引号标记即可。

总结

你想要的完全原生的['x', ()]语法是不可能实现的,因为内置列表的同构限制是在语法脱糖的第一步就生效的,你只能选择上面两种替代方案,或者手动用:*拼接。

内容的提问来源于stack exchange,提问作者Joseph Sible-Reinstate Monica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 06:36:03