Haskell:使用 RankNTypes 折叠记录构造函数

2024-04-21

import Data.ConfigFile

data Test = Test 
  { field1 :: Int
  , field2 :: Bool
  , field3 :: String
  } deriving (Show)

whatMyConfigLooksLike = 
    [ ("field1", "5")
    , ("field2", "True")
    , ("field3", "I am a string")
    ]

options = fst . unzip $ whatMyConfigLooksLike

readConfigFile = do
  rv <- runErrorT $ do 
    cp <- join . liftIO $ readfile emptyCP "theconfig.cfg"
    let printn = liftIO . putStrLn
        getn = get x "DEFAULT"
        x = cp
    printn "Loading configuration file..."
    -- I don't want to do the following
    one <- getn "field1"
    two <- getn "field2"
    three <- getn "field3"
    return $ Test one two three -- ...
    -- ... and so on because I have a data type with many fields

    -- I want to fold them onto the data constructor instead
    return $ foldl (\f s -> getn s >>= f) (Test) options
    -- but I think this doesn't type check because f's type is constantly changing?
  print rv

在上面的代码中,我有一个具有非常多态类型的 lambdafoldl (\f s -> getn s >>= f)。据我所知,这会导致它在接下来的递归中不进行类型检查。

我认为我可以使用 RankNTypes 语言扩展来定义一个多态递归类型,该类型可以表示函数的任何部分应用,从而允许函数进行类型检查。然而,通过实验、大量的尝试和同等数量的错误,我一直无法想出任何可以编译的东西。

如果有人可以向我展示如何根据上面的示例代码实现 RankNTypes 扩展(或建议替代方案),我将非常感激。我正在使用 GHC 7.4.2。


你想做的事是不可能的。类型检查器不知道列表中有多少元素,因此也不知道您尝试将多少参数传递给构造函数。确实如此,但这对于静态检查语言来说是无关紧要的。

RankNTypes 不会有帮助,因为根本问题不是你的 lambda 的类型(即使这是类型检查器抛出错误的地方。问题出在你的累加器上:foldl有类型(a -> b -> a) -> a -> [b] -> a;请特别注意,无论您向类型检查器抛出多少扩展,累加器在折叠中的每个点都必须具有相同的类型。Test有类型Int -> Bool -> String -> Test;它的第一个部分应用程序具有类型Bool -> String -> Test,并且没有办法统一这些类型。

但是,如果程序的其余部分类型正确,您应该能够简单地使用liftM3 Test (getn "field1") (getn "field2") (getn "field3")作为您的返回,这比您尝试的内容更详细,也更清晰。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell:使用 RankNTypes 折叠记录构造函数 的相关文章

  • 如何判断Python对象是否是字符串?

    如何检查 Python 对象是否是字符串 常规字符串或 Unicode Python 2 Use isinstance obj basestring 对于要测试的对象obj Docs https docs python org 2 7 li
  • 整数转浮点数

    这段代码的工作原理 posToXY Float gt Float gt Integer posToXY a b do let y a b round y 但这不起作用 posToXY Integer gt Integer gt Intege
  • 我可以在 where 子句中使用 or ( || ) 吗?

    我正在尝试延长Array类型 但我只希望类型为时可用的函数Int or Float 我知道我可以针对一种类型执行此操作 extension Sequence where Iterator Element Int 但我可以对多种类型执行此操作
  • 使用 LINQ 或 Lambda 从列表中删除实例?

    现在 我进入了一个阶段 将所有数据作为缓存 对象 中的列表获取 接下来要做的就是从列表中删除一些实例 通常 我会像这样删除 List
  • Haskell:找不到模块“Data.List.Split”

    我正在尝试在 Haskell 中拆分列表 据我所知 最简单的方法是splitOn 但是这个函数需要Data List Split 所以我尝试运行import Data List Split在前奏曲中 但是 我收到以下错误 Could not
  • 为什么 Haskell 中有协函子和逆变函子的区别,而范畴论却没有区别?

    这个答案是从范畴论的角度来看的 https math stackexchange com a 661989 72174包括以下语句 事实是 协函子和逆变函子之间没有真正的区别 因为每个函子只是一个协变函子 More in details a
  • 使用 linq 组合对象

    我有一个类的 2 个实例 它实现了IEnumerable界面 我想创建一个新对象并将它们合并为一个 我明白我可以使用for each去做这个 有 linq lambda 表达式的方法可以做到这一点吗 EDIT public class Me
  • 如何让 Show 显示函数名称?

    作为一个让我熟悉 Haskell 的简单练习 在 Youtube 上闲逛并偶然进入美国倒计时游戏节目之后 我想为数字游戏制作一个求解器 你得到 6 个数字 需要将它们与 为了得到给定的结果 到目前为止我所得到的是非常脑死亡的 let ope
  • “System.Int32”类型的表达式不能用于返回类型“System.Object”

    我正在尝试制作一个简单的脚本系统 用于打印标签 我过去曾通过反射完成此操作 没有任何问题 但我现在尝试使用 Lambda 函数来完成此操作 以便可以缓存函数以供重用 到目前为止我的代码如下 public static string GetV
  • 如何从 haskell 中的 IOError 获取 errno?

    我在 haskell 平台上 GHC 6 12 1 作为 apt get 安装在 Debian Squeeze 上 鉴于我需要在与最初引发它的线程不同的线程上使用它 如何从 IOError 中获取底层 errno 我需要这个的原因是因为我正
  • 将数据类型设置为 Kind * -> * 这不是函子

    布伦特 约尔吉类型分类百科全书 https www haskell org haskellwiki Typeclassopedia给出以下练习 举一个类型的例子 gt 不能将其制成 的实例Functor 不使用undefined 请告诉我什
  • Haskell scala 互操作性

    我是 Scala 初学者 来自面向对象范式 在了解 Scala 的函数式编程部分时 我被引导到 Haskell 纯函数式编程语言 探索 SO 问题答案 我发现 Java Haskell 具有互操作性 我很想知道 Scala Haskell
  • 我应该在 Turtle 或 Foldl 包中使用折叠吗?

    我在使用 Turtle 时遇到了一些困难 直到盯着难以理解的错误消息几分钟后才意识到我使用了错误的fold功能 https hackage haskell org package turtle 1 5 8 docs Turtle Shell
  • Java8 lambda 是否像匿名类一样维护对其封闭实例的引用?

    We know https stackoverflow com questions 5054360 do anonymous classes always maintain a reference to their enclosing in
  • 如何使用AWK脚本检查表的所有列数据类型? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 在这里 我正在检查表中第一列的数据类型 但我想知道AWK中表的所有列数据类型 我尝试过 但只能获得一列数据类型 例如 Column 1
  • ASP.NET MVC 3 Razor DisplayFor 委托

    我收到此错误 模板只能与字段访问 属性访问 一维数组索引或单参数自定义索引器表达式一起使用 这是我的代码 自定义 HTML 帮助程序 包装 DisplayFor 以便我可以选择模板 public static string DisplayL
  • 将两个 Int 值相除以获得 Float 的正确方法是什么?

    我想分两份IntHaskell 中的值并获得结果Float 我尝试这样做 foo Int gt Int gt Float foo a b fromRational a b 但 GHC 版本 6 12 1 告诉我 无法将预期类型 Intege
  • Haskell - 用防护罩替换外壳

    我想知道在这部分代码中是否可以用守卫替换 case 语句 firstFunction String gt Maybe MyType secondFunction MyType gt Integer myFunction String gt
  • 在 lambda 中延迟初始化和缓存内部值的简洁方法

    首先用简单的方法让代码自己说话 int heavy calc needed to be called once sleep 7500000 years return 42 int main auto foo And cached for l
  • 使用 FoldLine 解析多个块

    对于这个简化的问题 我试图解析一个如下所示的输入 foo bar baz quux woo hoo xyzzy glulx into foo bar baz quux woo hoo xyzzy glulx 我尝试过的代码如下 import

随机推荐