gpt4 book ai didi

haskell - 如何从纯函数中调用不纯函数?

转载 作者:行者123 更新时间:2023-12-03 14:56:27 25 4
gpt4 key购买 nike

我刚刚读完一本“Learn You a Haskell for Great Good”!书,所以我的问题可能很幼稚。
我不明白的是如何从纯代码中调用“不纯”的 IO 函数。

这是一个用 C# 编写的工作示例。在我们的业务逻辑中,我们根据天气计划一些行动。我们以通常的 C# 方式进行操作。

interface IWeatherForecast
{
WeatherData GetWeather(Location location, DateTime timestamp);
}

// concrete implementation reading weather from DB
class DbWeather : IWeatherForecast
{
public override WeatherData GetWeather(Location location, DateTime timestamp)
{...}
}

class WeatherFactory
{
public IWeatherForecast GetWeatherProvider()
{...}
}

// Business logic independent from any DB
class MaritimeRoutePlanner
{
private IWeatherForecast weatherProvider = weatherFactory.GetWeatherProvider();

public bool ShouldAvoidLocation(Location location, DateTime timestamp)
{
WeatherData weather = weatherProvider.GetWeather(location, timestamp);
if(weather.Beaufort > 8)
return true;
else...
...
}
}

如何在 Haskell 中实现这个逻辑?

实际上,“纯逻辑”MaritimeRoutePlanner 调用 weatherProvider.GetWeather()这是“不纯的IO”的东西。

在 Haskell 中可以吗?你会如何在 Haskell 中建模呢?

最佳答案

一般问题(如何从纯函数调用不纯函数)是一个常见问题解答。参见例如这个问题及其答案:How to return a pure value from a impure method

与软件架构相关的任何其他主题一样,如何以更实用的方式构建代码取决于具体情况。你在写什么样的程序?一个 REST API?智能手机应用程序?控制台程序?批处理作业?一个插件?

在许多情况下,你可以摆脱我所说的不纯-纯-不纯三明治:

  • 从不纯的来源收集所有必需的数据
  • 使用该数据调用纯函数
  • 用纯函数
  • 的返回值做一些不纯的事情

    在 Haskell 中你可以这样做,因为入口点总是不纯的。这是天气决策问题的简单草图。您首先定义您将处理的数据。在这里,我只包括 beaufort值,但我假设 WeatherData将包含比这更多的数据(这就是为什么我将其定义为 data 而不是 newtype )。
    data WeatherData = WeatherData { beaufort :: Int } deriving (Eq, Show)

    您现在可以将决策逻辑编写为纯函数:
    shouldAvoidLocation :: WeatherData -> Bool
    shouldAvoidLocation weather = beaufort weather > 8

    加载数据是一个完全具体的操作:
    readWeatherFromDb :: Location -> LocalTime -> IO WeatherData
    readWeatherFromDb location timestamp = -- implementation goes here...

    这里没有明确的抽象。该函数读取数据并返回不纯的数据。这可能是不纯-纯-不纯三明治的第一步(不纯)。

    现在可以根据该架构来构建应用程序的入口点:
    main :: IO ()
    main = do
    w <- readWeatherFromDb Berlin $ LocalTime (fromGregorian 2019 8 29) (TimeOfDay 8 55 8)
    if shouldAvoidLocation w
    then putStrLn "Avoid"
    else putStrLn "Go"

    调用 shouldAvoidLocation是三明治中间的纯正的好东西,然后是不纯的 putStrLn来电。

    关于haskell - 如何从纯函数中调用不纯函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57703898/

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