我也有功能:
higherOrderPure :: (a -> b) -> c
effectful :: Monad m => (a -> m b)
Run Code Online (Sandbox Code Playgroud)
我想将第一个函数应用于第二个函数:
higherOrderPure `someOp` effectful :: Monad m => m c
Run Code Online (Sandbox Code Playgroud)
哪里
someOp :: Monad m => ((a -> b) -> c) -> (a -> m b) -> m c
Run Code Online (Sandbox Code Playgroud)
例:
curve :: (Double -> Double) -> Dia Any
curve f = fromVertices $ map p2 [(x, f x) | x <- [1..100]]
func :: Double -> Either String Double
func _ = Left …Run Code Online (Sandbox Code Playgroud) 例如,可以创建类型的函数f :: Monad m => [m a] -> m [a],但是不可能将类型的函数g :: Monad m => m [a] -> [m a]作为对前者的适当的反函数.(IE: f . g = id)
我想了解可以使用哪些规则来确定是否可以构造该类型的函数,以及如果这些类型违反这些规则,则无法构造这些类型的原因.
a -> m bfrom to函数m (a -> b)在编程中很少出现,但可以在 Reader monad 中制作。以下代码是暂定的实现。这样的图书馆存在吗?
class Monad m => MonadShift m where
shift :: (a -> m b) -> m (a -> b)
instance MonadShift Identity where
shift f = Identity (\x -> runIdentity (f x))
instance MonadShift m => MonadShift (ReaderT r m) where
shift f = ReaderT (\r -> shift (\x -> runReaderT (f x) r))
Run Code Online (Sandbox Code Playgroud) 我编写了一个程序来Maybe从一对中取出一个:
deMaybe :: (a, Maybe b) -> Maybe (a, b)
deMaybe (_, Nothing) = Nothing
deMaybe (x,Just y) = Just (x, y)
Run Code Online (Sandbox Code Playgroud)
我知道这Maybe是一个单子并且(,) a是一个函子(以及其他类型类)。我想知道是否缺少更高级别的功能,例如:
commute :: (Functor f, Monad m) => f (m a) -> m (f a)
Run Code Online (Sandbox Code Playgroud)
我的问题是:我可以deMaybe使用更通用的类型签名(例如假设的类型签名)来编写commute,承认我正在尝试将一个函子传递到另一个函子吗?fmap可以使用、>>=、 、 &c等函数来完成此操作吗pure?
考虑以下示例函数,它们均向纯输入添加随机值:
addRand1 :: (MonadRandom m) => m (Int -> Int)
addRand2 :: (MonadRandom m) => Int -> m Int -- *can* be written as m (Int -> Int)
Run Code Online (Sandbox Code Playgroud)
这是很容易转换addRand1成一个函数相同的签名addRand2,而不是相反。
对我来说,这提供了强有力的证据,我应该写addRand1了addRand2。在此示例中,addRand1具有更真实/更通用的类型,通常在Haskell中捕获重要的抽象。
虽然有“正确的”签名似乎函数式编程的一个重要方面,我也有很多的实际原因addRand2可能是一个更好的签名,即使它可能与写入addRand1的签名。
带接口:
class FakeMonadRandom m where
getRandom :: (Random a, Num a) => m a
getRandomR1 :: (Random a, Num a) => (a,a) -> m a
getRandomR2 :: (Random a, Num a) …Run Code Online (Sandbox Code Playgroud)为了用一个简单的例子说明这一点,请说我已经实现了filter:
filter :: (a -> Bool) -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)
我有一个p与现实世界相互作用的谓词:
p :: a -> IO Bool
Run Code Online (Sandbox Code Playgroud)
如何在filter不编写单独的实现的情况下使其工作:
filterIO :: (a -> IO Bool) -> [a] -> IO [a]
Run Code Online (Sandbox Code Playgroud)
大概如果我可以p变成p':
p': IO (a -> Bool)
Run Code Online (Sandbox Code Playgroud)
然后我就能做到
main :: IO ()
main = do
p'' <- p'
print $ filter p'' [1..100]
Run Code Online (Sandbox Code Playgroud)
但我一直无法找到转换.
编辑: 正如人们在评论中指出的那样,这样的转换没有意义,因为它会破坏IO Monad的封装.
现在的问题是,我可以构建我的代码,以便纯和IO版本不完全复制核心逻辑吗?