小编Ste*_*orn的帖子

如何从纯函数调用不纯函数?

我刚读完“学到Haskell来造福伟大!”。书,所以我的问题可能很幼稚。我不明白的是如何从纯代码中调用“不纯”的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...
            ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如何在Haskell中实现此逻辑?

实际上,“纯逻辑” MaritimeRoutePlanner称之为weatherProvider.GetWeather() …

haskell functional-programming

6
推荐指数
2
解决办法
303
查看次数

Haskell 中是否有任何终止折叠?

如果我已经有了我想要的数据,我需要某种折叠可以终止。

例如,我需要找到前 3 个大于 5 的数字。我决定使用任一终止,我的代码如下所示:

    terminatingFold :: ([b] -> a -> Either [b] [b]) -> [a] -> [b]
    terminatingFold f l = reverse $ either id id $ fold [] l
      where fold acc [] = Right acc
            fold acc (x:xs) = f acc x >>= flip fold xs

    first3NumsGreater5 acc x =
      if length acc >= 3
        then Left acc
        else Right (if x > 5 then (x : acc) else acc)
Run Code Online (Sandbox Code Playgroud)

是否有一些更聪明/通用的方法?

haskell functional-programming exit fold

6
推荐指数
2
解决办法
310
查看次数

这些线程会永远阻塞吗?

我目前正在阅读 Simon Marlow 的书“ Haskell 中的并行和并发编程”,但我不明白这段代码:

waitAny :: [Async a] -> IO a
waitAny as = do
  m <- newEmptyMVar
  let forkwait a = forkIO $ do r <- try (wait a); putMVar m r
  mapM_ forkwait as
  wait (Async m)
Run Code Online (Sandbox Code Playgroud)

这里我们调用 putMVar N 次,但我们只有 1 次等待操作。我是否理解 N-1 个线程在尝试执行 putMVar 时会被阻塞?这里发生了什么?

...或超级简化:

test = do
  m <- newEmptyMVar
  forkIO $ putMVar m 1
  forkIO $ putMVar m 2
  a <- readMVar m
  return a
Run Code Online (Sandbox Code Playgroud)

为什么它可以毫无问题地工作?为什么我没有异常:线程在 MVar 操作中被无限期阻塞

concurrency haskell

6
推荐指数
1
解决办法
132
查看次数

如何为两个参数都具有相同类型的对编写monad实例?

假设我有一个对类型:

data Pair a = Pair a a
Run Code Online (Sandbox Code Playgroud)

为它编写monad实例的正确方法是什么?我的想法大致是这样的:

instance Semigroup a => Semigroup (Pair a) where
  Pair a1 a2 <> Pair b1 b2 = Pair (a1 <> b1)(a2 <> b2)

instance Monad Pair where
  return = pure
  (Pair a b) >>= f = f a <> f b
Run Code Online (Sandbox Code Playgroud)

这是对的吗?如果是这样,那么在对中指定b型中的b类型是一个半群?

monads haskell

4
推荐指数
1
解决办法
124
查看次数

如何修复Haskell中的“无法匹配预期类型”错误?

我是Haskell的新手,现在正在学习类型课程。我创建了一个简单的类型类,但不幸的是我无法修复

无法匹配预期的类型

-- So a can be Int, Float etc
data MyShape a = Circle a -- etc like | Rectangle a a 
  deriving(Show)

class Geo a where
  inflate :: Num b => a -> b -> a
  area :: Num b => a -> b

instance Num a => Geo (MyShape a) where
  inflate (Circle r) x = Circle (r * x)
  area (Circle r) = 3 * r * r
Run Code Online (Sandbox Code Playgroud)

它既不喜欢充气功能,也不喜欢区域功能。

错误:

• Couldn't match expected type ‘a’ …
Run Code Online (Sandbox Code Playgroud)

haskell

1
推荐指数
1
解决办法
69
查看次数