gpt4 book ai didi

haskell - 与 API 对话的最佳实践

转载 作者:行者123 更新时间:2023-12-01 03:41:19 25 4
gpt4 key购买 nike

我正在尝试为 Haskell 中的 API 创建一些绑定(bind)。我注意到一些函数有大量的参数,例如

myApiFunction :: Key -> Account -> Int -> String -> Int -> Int -> IO (MyType)

有这么多争论本身并不一定是坏事。但作为用户,我不喜欢长参数函数。但是,这些参数中的每一个都是绝对 100% 必要的。

有没有一种更 haskell 式的方法来抽象这些函数的公共(public)部分?这里过去的所有帐户都用于构建 URL,所以我需要它可用,它代表什么完全取决于功能。但有些事情是一致的,比如 KeyAccount ,我想知道对这些论点最好的抽象是什么。

谢谢!

最佳答案

您可以将它们组合成更具描述性的数据类型:

data Config = Config
{ cKey :: Key
, cAccount :: Account
}

那么也许有 type s 或 newtypes使其他参数更具描述性:
-- I have no idea what these actually should be, I'm just making up something
type Count = Int
type Name = String
type Position = (Int, Int)

myApiFunction :: Config -> Count -> Name -> Position -> IO MyType
myApiFunction conf count name (x, y) =
myPreviousApiFunction (cKey conf)
(cAccount conf)
name
name
x
y

如果 Config总是需要的,那么我建议在 Reader 工作monad,你可以很容易地做到这一点
myApiFunction
:: (MonadReader Config io, MonadIO io)
=> Count -> Name -> Position
-> io MyType
myApiFunction count name (x, y) = do
conf <- ask
liftIO $ myPreviousApiFunction
(cKey conf)
(cAccount conf)
name
name
x
y

这使用 mtl monad 转换器库。如果您不想一遍又一遍地键入该约束,您也可以使用 ConstraintKinds扩展别名:
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
...

type ApiCtx io = (MonadReader Config io, MonadIO io)

...

myApiFunction
:: ApiCtx io
=> Count -> Location -> Position
-> io MyType
myApiFunction ...

根据您的特定应用程序,您还可以将其拆分为多个功能。在此之前,我已经看过很多 API,例如
withCount :: ApiCtx io => Count    -> io a -> io a
withName :: ApiCtx io => Name -> io a -> io a
withPos :: ApiCtx io => Position -> io a -> io a

(&) :: a -> (a -> b) -> b

request :: ApiCtx io => io MyType
> :set +m   -- Multi-line input
> let r = request & withCount 1
| & withName "foo"
| & withPos (1, 2)
> runReaderT r (Config key acct)

这些只是少数几种技术,还有其他技术,但在此之后它们通常开始变得更加复杂。其他人对如何做到这一点会有不同的偏好,我相信很多人会不同意我对其中一些是否是好的做法(特别是 ConstraintKinds ,它没有被普遍接受)。

如果你发现自己的类型签名太大了,即使在应用了其中一些技术之后,那么也许你是从错误的方向解决问题,也许这些功能可以分解成更简单的中间步骤,也许是一些这些参数可以在逻辑上组合成更具体的数据类型,也许你只需要一个更大的记录结构来处理设置复杂的操作。它现在非常开放。

关于haskell - 与 API 对话的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30533353/

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