在上给出了一个解释,为什么像在scalaz、cat (Scala)或Arrow (Kotlin)中的验证不能是单一的。
据我所知,这是因为他们已经从应用函子的角度对一元进行了建模,而作为应用程序(收集所有的残废者)所期望的验证行为不同于单一验证(序列验证,在第一个无效的情况下快速失败)。因此,当您希望快速失败时,您需要将一个验证转换为一个“或者”(这是一个单变量)。
在上,他们提到了验证不是单一的原因,是因为以下属性无法保存:
x <|*|> y === x >>= (a => y map ((a, _)))
但是从monad的定义来看,上面的属性并不是的一部分
上下文
标题中的问题实际上是我所遇到的一个特定问题的通用版本。请随意回答下面的一般性问题或这个具体问题。
我正在实现一些函数,它遍历一个纯非类型化的lambda演算AST,并将变量替换为De索引。AST有两种表示形式:外部表示(带有变量名称)和内部表示(带有索引):
type Id = String
data TermEx
= VarE Id
| LamE Id TermEx
| AppE TermEx TermEx
我正在重构一些旧代码,这些代码是多态的,但类型受类约束,是单变量:
class ( MonadIO m
, MonadLogger m
, MonadLoggerIO m
, MonadThrow m
, MonadCatch m
, MonadMask m
, MonadBaseControl IO m
, MonadUnliftIO) => HasLogging m where
在较旧的代码中,应用程序的主要单元是..。
type AppM = ReaderT Env IO
...which现在将改为
假设我有一个高阶函数,它使用从函数参数中检索到的值来执行一些计算。
f :: a -> (b -> c) -> d
其中a,b,c,d是一些具体的类型。
然后我就有了一个这种类型的函数
g :: b -> m c
其中m是某个单子。
现在有没有一种方法可以把g和f一起使用,也就是把f变成一个函数,它产生m d而不是d,并且可以使用g作为它的第二个参数?
一个具体的例子是,m是IO monad,f是计算从其函数参数中检索到的n个数字的和的函数,g从标准输入中读取一个数字。
f n g = sum $ map g (1..n)
g :: Int -> IO Int
g
在所有的monad transformers中,我们总是有这样的结构吗?如果是,那为什么呢?如果不是,那么何时从另一个中选择一个?
newtype MaybeOT m a = MaybeOT {runMaybeOT :: Maybe (m a) }
instance (Monad m) => Monad (MaybeOT m) where
return = pure
(MaybeOT mma) >>= f = MaybeOT $
case mma of
Nothing
这是关于Haskell中的语法糖。一个简单的Haskell程序:
main = do
args <- getArgs
let first = head args
print first
我在第一行(args <- getArgs)使用绑定,在第二行(let first = ...)使用纯赋值。有没有可能把它们合并成一个可读的一行程序?
我知道我可以重写绑定“去糖化”:
main = do
first <- getArgs >>= ( return . head )
print first
但是有没有一种更好的方法,不用(>>=)和r
我是Haskell的新手,学习函子、应用程序和Monad。
我从hackage中检查了Either类型的函子实例如下:
data Either a b = Left a | Right b
instance Functor (Either a) where
fmap _ (Left x) = Left x
fmap f (Right y) = Right (f y)
我被要求执行扩展Either的函子、应用程序和Monad实例,称为MyEither。
data MyEither a b = MyLeft a | MyRight b | Nothing
der
我在haskell中获得了以下数据类型:
data Flow a = Continue a | Return Value
newtype FlowT m a = FlowT {runFlowT :: m (Flow a)}
type IStateM a = FlowT (StateT IState IO) a
其中IState是包含一些列表等的记录类型。FlowT的Monad和MonadTrans实例定义如下:
instance (Monad m) => Monad (FlowT m) where
x >>= f = FlowT $ do
在用monad变压器构建一个用于编写库的monad堆栈时,我遇到了一个关于它的行为的问题。
以下代码不会传递类型检查器:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Foo (FooM, runFooM, foo) where
import Control.Applicative
import Control.Monad.Reader
newtype FooM m a = FooM { runFooM :: ReaderT Int m a }
deriving (Functor, Applicative, Monad, Mona
当我在ghci中查找有关(->)的信息时,我对(->)非常感兴趣。上面写着,
data (->) a b -- Defined in `GHC.Prim`
到目前为止还不错,但后来它变得非常有趣,当它说-
instance Monad ((->) r) -- Defined in `GHC.Base`
instance Functor ((->) r) -- Defined in `GHC.Base`
这意味着什么?为什么GHC将它定义为Monad的一个实例,以及(->)的函子
哈斯克尔是新来的,我正试着弄清楚这件蒙纳德的事。一元绑定运算符-- >>= --具有非常特殊的类型签名:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
为了简化,让我们用Maybe代替m:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
然而,请注意,定义可以用三种不同的方式编写:
(>>=) :: Maybe a -> (Maybe a -> Maybe b) -> Maybe b
(>>
我有一条运行良好的铁路管道样本:
open FSharpPlus
let funA n =
if n < 10 then Ok n
else Error "not less than 10"
let funB n =
if n < 5 then Ok (n, n * 2)
else Error "not less than 5"
let funC n = // int -> Result<(int * int), string>
n
|> funA
>>
尝试使用Chart学习Haskell。构建过程中的包中断:
/private/var/folders/m2/qwhdrn_d46z99_3vxchdwn7r0000gn/T/stack5630/Chart-1.9/Graphics/Rendering/Chart/State.hs:102:3: error:
• No instance for (Control.Monad.Fail.MonadFail Identity)
arising from a do statement
with the failable pattern ‘(c : cs)’
我试图创建一个在[Maybe a]上工作的fmap。但是,也许一个有类的*,而fmap要求有类的* -> *。这导致了以下不幸的解决办法:
newtype Unfortunate a = Unfortunate ([Maybe a]) deriving Show
instance Functor Unfortunate
where fmap f (Unfortunate a) = Unfortunate $ (fmap (fmap f)) a
-- |
-- >>> l = Unfortunate [Just 10, Just 1, Nothing, Ju
在Haskell中,应用程序被认为比函子强,这意味着我们可以使用类应用程序来定义函子。
-- Functor
fmap :: (a -> b) -> f a -> f b
fmap f fa = pure f <*> fa
单子被认为比应用程序强&函子,这意味着。
-- Functor
fmap :: (a -> b) -> f a -> f b
fmap f fa = fa >>= return . f
-- Applicative
pure :: a -> f a
pure = return
(<*>
我试图为Monad和MonadState实例提供计算(>>=), return, get和put操作数量的State'实例。
data Counts = Counts { binds :: Int
, returns :: Int
, gets :: Int
, puts :: Int
}
newtype State' s a = State' { runState' :: (s, Counts)
我试图使用管道来建模一个双向Proxy实例最理想的问题。基本上,我有类似于以下架构的内容:
api logic
| ^
| |
v |
A A'
layer 1
B B'
| ^
| |
v |
layer 2
基本上,我有一个layer 1,它是一个双向变压器。该模型是基于拉的,因此我的消息流转换将由从logic组件中的拉触发。
所以我应该让layer1 :: Proxy A' A B' B m x,即layer1从api中提取A,进行一些转换A -> B,然后使用l
描述自由单元的一种方法是说它是C范畴中的一个初值幺半群,其对象是从C到C的对象,箭头是它们之间的自然变换。如果我们把C设为Hask,那么在haskell中,即所谓的Functor,它是* -> *的函子,*表示Hask的对象。
通过初始化,在t中,从一个内射体m到一个单类m的任何映射都会诱导出一个从Free t到m的映射。
否则,从函子t到Monad m的任何自然转换都会引发从Free t到m的自然转换。
我本来希望能写一个函数
free :: (Functor t, Monad m) => (∀ a. t a → m a) → (∀ a. Free t a → m a)
free
从数学上讲,函数应用的二进制运算是一个内函子/Monad.
pipe :: (a -> b) -> a -> b
pipe = \f -> \a -> f a
(|>) :: a -> (a -> b) -> b
(|>) = flip pipe
infixl 1 |>
它被称为管道操作符,在Haskell中,预定义为
(&) :: a -> (a -> b) -> b
monadTestPipe :: IO ()
monadTestPipe = do
"Monad Laws=====
我想在我的代码中表示一个上限的概念,所以我创建了一个有区别的联合: data UpperBound a = UpperBound a | DoNotCare deriving (Eq, Read, Show) 然后,我手动派生了几个有用的类型类实例(用于学习目的): instance Functor UpperBound where
fmap _ DoNotCare = DoNotCare
fmap f (UpperBound x) = UpperBound $ f x
instance Applicative UpperBound where
pure = Upp
我刚刚阅读了这篇非常有趣的文章,内容是关于Monad提示符的另一种实现:
下面是可以运行的简化代码:
data Request a where
GetLine :: Request String
PutStrLn :: String -> Request ()
data Prompt p r
= forall a. Ask (p a) (a -> Prompt p r)
| Answer r
instance Monad (Prompt p) where
return = Answer
Ask req