我刚读完“学到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() …
如果我已经有了我想要的数据,我需要某种折叠可以终止。
例如,我需要找到前 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)
是否有一些更聪明/通用的方法?
我目前正在阅读 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 操作中被无限期阻塞?
假设我有一个对类型:
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类型是一个半群?
我是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)