gpt4 book ai didi

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

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

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

在上面的代码中,我有一个非常多态类型的 lambda foldl (\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")作为您的返回,这比您尝试的要冗长和清晰得多。

关于Haskell:使用 RankNTypes 折叠记录构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16490846/

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