我没有我要找的名字...(我将立即更新此问题的标题...)。
这里是上下文:
data EventStoreMicroService = EventStoreMicroService {
urlHost :: String,
port :: Int,
username :: ByteString,
password :: ByteString}
getCredentials :: EventStoreMicroService -> EventStore.Credentials
getCredentials EventStoreMicroService {username,password} = EventStore.credentials username password
getConnectionType :: EventStoreMicroService -> EventStore.ConnectionType
getConnectionType EventStoreMicroService {urlHost,port} = (EventStore.Static urlHost port)
getEventStoreSettings :: EventStoreMicroService -> EventStore.Settings
getEventStoreSettings service = EventStore.defaultSettings
我具有此功能:
connect :: Settings -> ConnectionType -> IO Connection
这是我到目前为止所做的:
let microservice = EventStoreMicroService {
urlHost = "127.3.4.5",
port = 2000,
username = "xxxx",
password = "yyy"}
eventStoreSettings = getEventStoreSettings microservice
eventStoreConnectionType = getConnectionType microservice
connect eventStoreSettings eventStoreConnectionType
我正在寻找一个神奇的函数(我将其命名为“ from”),该函数将能够以这种方式表达它:
let microservice = EventStoreMicroService {
urlHost = "127.3.4.5",
port = 2000,
username = "xxxx",
password = "yyy"}
eventStoreSettings = getEventStoreSettings microservice
eventStoreConnectionType = getConnectionType microservice
connect $ from microservice getEventStoreSettings getConnectionType
它基本上将2个函数应用于数据类型,该数据类型返回让说(a,b)并将该元组提供给函数connect ...
答案 0 :(得分:3)
所以我认为您正在追求这样的事情?
from :: a -> (a -> b) -> (a -> b) -> (b, b)
from a f g = (f a, g a)
然后您可以像这样使用它:
uncurry connect $ from microservice getEventStoreSettings getConnectionType
我确定标准库中可能存在类似from
的内容,但是在Hoogle上进行快速搜索后找不到任何内容。
编辑:正如@WillNess在评论中指出的那样,可以通过几种方式对此进行改进。
首先,我上面的from
版本可以简化为from a f g = (f &&& g) a
。
第二,您可以通过定义更通用的uncurry
版本来避免使用from
:
from' :: (b -> b -> c) -> a -> (a -> b) -> (a -> b) -> c
from' c a f g = c (f a) (g a)
允许一个人简单地做:
from' connect microservice getEventStoreSettings getConnectionType
答案 1 :(得分:2)
请注意,您实际上并不需要魔术功能。仅将现有的Applicative
实例用于函数可能会更清楚。
data EventStoreMicroService = EventStoreMicroService {
urlHost :: String,
port :: Int,
username :: ByteString,
password :: ByteString}
getCredentials :: EventStoreMicroService -> EventStore.Credentials
getCredentials = EventStore.Credentials <$> username <*> password
getConnectionType :: EventStoreMicroService -> EventStore.ConnectionType
getConnectionType = EventStore.Static <$> urlHost <*> port
getEventStoreSettings :: EventStoreMicroService -> EventStore.Settings
getEventStoreSettings _ = EventStore.defaultSettings
-- or getEventStoreSettings = const EventStore.defaultSettings
然后
let microservice = EventStoreMicroService { urlHost = "127.3.4.5"
, port = 2000
, username = "xxxx"
, password = "yyy"
}
(connect <$> getEventStoreSettings <*> getConnectionType) microservice
-- or skip getEventStoreSettings, and use defaultSettings directly
-- connect EventStore.defaultSettings (getConnectionType microservice)