如何将[TExp a]转换为TExp [a],或者以编程方式将fineTH应用于多个值?

问题描述 投票:2回答:1

我最近在Haskell中一直将refined用于细化类型,并且遇到了主要的可用性问题。我无法弄清楚如何在编译时优化整个值列表。

例如,我可以写:

{-# LANGUAGE TemplateHaskell #-}

import Refined

oneToThree :: [Refined Positive Int]
oneToThree = [$$(refineTH 1), $$(refineTH 2), $$(refineTH 3)]

但是我不能这样做,不能使用范围语法,因为Refined没有(出于充分的理由)没有Enum的实例。

我希望能够做类似的事情

oneToThree :: [Refined Positive Int]
oneToThree = $$(refineTH <$> [1..3])

但是由于无法将[TExp (Refined Positive Int)]提升到TExp [Refined Positive Int],所以我无法编译它。

是否有我缺少的模板haskell魔术能让我做到这一点?

如果有人提出建议,也将接受关于更好的轻量级精炼类型库的建议。

haskell template-haskell
1个回答
0
投票

此方法有效(由于阶段限制,它必须与您使用的文件位于不同的文件中:]

import Language.Haskell.TH.Syntax (Exp(ListE), TExp(TExp))

makeTypedTHList :: [TExp a] -> TExp [a]
makeTypedTHList xs = TExp $ ListE [x | TExp x <- xs]

然后您将像这样使用它:

{-# LANGUAGE TemplateHaskell #-}

import Refined
import AboveCodeInSeparateModuleBecauseOfStageRestriction (makeTypedTHList)

oneToThree :: [Refined Positive Int]
oneToThree = $$(makeTypedTHList <$> traverse refineTH [1..3])

但是,自己调用TExp构造函数会破坏类型化的模板Haskell的某些安全性(尽管我认为这种特殊情况是安全的)。理想情况下,我更喜欢一种不需要这样做的方法,但我想不到一个。

© www.soinside.com 2019 - 2024. All rights reserved.