gpt4 book ai didi

haskell - 动态模块名称

转载 作者:行者123 更新时间:2023-12-02 18:01:30 26 4
gpt4 key购买 nike

我想在 Haskell 中做这样的事情,但编译器不允许我这样做。

有什么办法可以完成这个任务吗?

-- both modules export function named "hello"
-- and I want to run it in every module
import qualified MyMod as M1
import qualified MyAnotherMod as M2

runmodules = map (\m -> m.hello) [M1, M2]

最佳答案

恐怕 Haskell 中的模块根本不是这所需要的一流实体。

但是,正如 bzn 评论的那样,Template Haskell可以用于解决这样的问题。结果可能有点笨拙,但如果您确实需要一些快速的元编程技巧,那么这不是一个坏选择。我并不是真正的 TH 专家,但你想要的非常简单,有一个问题:据我所知,“不明确的标识符”和“模块名称”都不能以任何方式捕获或引用,所以你'必须将它们放入作为 TH 函数参数给出的字符串中。

这是一个快速但简单的简单示例:

{-# LANGUAGE TemplateHaskell #-}
module MapModuleTH where

import Language.Haskell.TH

mapQual :: [String] -> String -> ExpQ
mapQual ms n = listE $ map (\m -> varE . mkName $ m ++ "." ++ n) ms

mapMQual :: [String] -> String -> ExpQ
mapMQual ms n = appE (varE 'sequence) $ listE $ map (\m -> varE . mkName $ m ++ "." ++ n) ms

您将事情表述为“运行函数”,这听起来更像是执行一堆 IO 操作,而不仅仅是收集内容列表,因此我添加了一个也对结果进行排序的变体。

请注意,尽管这里使用了字符串,但这个 仍然是静态类型的——如果限定名称不存在,或者类型不匹配,您将得到预期的编译时错误,就像您手动写出所有内容一样。

这是一个使用它的快速示例。鉴于以下情况:

{-# LANGUAGE TemplateHaskell #-}
module MapModule where

import MapModuleTH
import qualified Test1 as T1
import qualified Test2 as T2

tests = do xs <- $(mapMQual ["T1", "T2"] "test")
putStrLn $ "Count: " ++ show (length xs)

假设其他模块在那里并定义了test,那么在GHCi中我们可以看到:

> tests
Test 1
Test 2
Count: 2

关于haskell - 动态模块名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8508702/

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