与…有关
https://stackoverflow.com/a/71020780/17053359
我们可以将非IO函数:f提升到使用return的IO函数,如
return . f现在,我想使这个f成为通用的,包括IO
f :: A -> IO A -- not IO to IO
f :: IO a -> IO a -- (no change, `id` instead of `return`)换言之:
如果typeOf f == io那么f
否则return . f
哈斯克尔的密码是什么?
编辑:
console.log(
Object(1)
);
console.log(
Object(Object(1))
);
console.log(
Object(Object(Object(1)))
);
发布于 2022-02-07 17:06:43
你几乎肯定不想这么做。所需的类型级别的黑客数量应该已经把你吓跑了,而这并不是单子应该被使用的方式。
纯粹出于教育目的,您可以定义一个函数pureish,如果参数不是IO a类型,它的行为就像return,如果参数是IO a类型,就像id一样。
type family PureishResult a where
PureishResult (IO a) = a
PureishResult a = a
class Pureish p where
pureish :: p -> IO (PureishResult p)
instance {-# OVERLAPPABLE #-} (PureishResult a ~ a) => Pureish a where
pureish = pure
instance Pureish (IO a) where
pureish = id别说我没警告你!
发布于 2022-02-07 21:41:27
这里是另一个版本的Prophet's answer,没有重叠的实例。
{-# language MultiParamTypeClasses, DataKinds, KindSignatures, TypeFamilies, TypeApplications, ScopedTypeVariables, AllowAmbiguousTypes, FlexibleInstances, FlexibleContexts #-}
type family GetUnderlying a where
GetUnderlying (IO a) = a
GetUnderlying a = a
type family IsIO a where
IsIO (IO _) = True
IsIO _ = False
class Pureish (isIO :: Bool) u a where
pureish' :: a -> IO u
instance Pureish False u u where
pureish' = pure
instance Pureish True u (IO u) where
pureish' = id
pureish :: forall a u. (Pureish (IsIO a) u a, u ~ GetUnderlying a) => a -> IO u
pureish = pureish' @(IsIO a)发布于 2022-02-07 20:19:46
我自己回答。
我完全不知道我的问题出了什么问题,也许我的提问方式是不够的。至少,我已经提到了幂等性和我的示例片段JS。但这是我的简单解决方案。
(+++) :: (a -> b) -> (b -> c) -> a -> c
(+++) = flip (.)
infixl 9 +++
someFunctor :: Show a => (a -> IO b) -> IO (R a) -> IO (R b)
someFunctor = \f -> \ioA -> do
print "-- someFunctor"
val <- ioA >>= _val
b <- (f +++ return +++ join) val
io b根据我以前的问答代码:
https://stackoverflow.com/questions/71021454
复制相似问题