Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 同质对的monad实例的已知/已建立用例_Haskell_Monads - Fatal编程技术网

Haskell 同质对的monad实例的已知/已建立用例

Haskell 同质对的monad实例的已知/已建立用例,haskell,monads,Haskell,Monads,有一次我问,哪个被正确地标记为的副本 现在我有一个疑问,对于一对同质类型的monad实例,是否有任何已知的用例 以下是其实例: 数据对a=对a派生显示 实例函子对,其中 fmap f(对AB)=对(对FA)(对b) 实例应用程序对,其中 纯a=对a 配对f g配对x y=配对(f x)(g y) 实例Monad对,其中 m>>=f=joinPair(fm) joinPair::对(对a)->对a joinPair(对(对x u)(对y))=对x y 我以前从未使用过这样的单子,但是在给出了这个例

有一次我问,哪个被正确地标记为的副本

现在我有一个疑问,对于一对同质类型的monad实例,是否有任何已知的用例

以下是其实例:

数据对a=对a派生显示
实例函子对,其中
fmap f(对AB)=对(对FA)(对b)
实例应用程序对,其中
纯a=对a
配对f g配对x y=配对(f x)(g y)
实例Monad对,其中
m>>=f=joinPair(fm)
joinPair::对(对a)->对a
joinPair(对(对x u)(对y))=对x y

我以前从未使用过这样的单子,但是在给出了这个例子之后,我看到了它的优点。这将计算两个笛卡尔坐标之间的距离。它实际上似乎非常有用,因为它自动将Xs上的任何操作与Ys上的任何操作分开

collapsePair :: (a -> a -> b) -> Pair a -> b
collapsePair f (Pair x y) = f x y

type Coordinates = Pair Float
type Distance = Float
type TriangleSides = Pair Distance

-- Calculate the sides of a triangle given two x/y coordinates
triangleSides :: Coordinates -> Coordinates -> TriangleSides
triangleSides start end = do
    -- Pair x1 y1
    s <- start

    -- Pair x2 y2
    e <- end

    -- Pair (x2 - x1) (y2 - y1)
    Pair (e - s) (e - s)
    
-- Calculate the cartesian distance
distance :: Coordinates -> Coordinates -> Distance
distance start end = collapsePair distanceFormula (triangleSides start end)
    where distanceFormula x y = sqrt (x ^ 2 + y ^ 2)
但是,我们可以通过人为地将1添加到X的末尾,使其依赖于
Monad

triangleSides' :: Coordinates -> Coordinates -> TriangleSides
triangleSides' start end = do
    s <- start
    e <- end
    Pair (e - s + 1) (e - s)

您可以验证此答案。

您的
对a
读卡器布尔a
/
布尔->a
同构:

to (Pair f t) = \b -> if b then t else f

from f = Pair (f False) (f True)

因此,的任何用例也是monad的潜在用例。这类数据类型的通用术语是可表示函子。

距离公式来自,其中三角形的斜边,
c
,在给定边的情况下被找到
a
b
a^2+b^2=c^2
。哦,好的。谢谢但是,我认为您不需要Monad实例。它比应用程序的
(-)end start
做的更多是什么?实际上,您可以执行
(.-)=liftA2(-)
,然后执行
结束。开始
,可读性强得多。(顺便说一句,发明者+1!)这是一个很好的观点,这个例子可以用Applicative而不是Monad来完成。(do块的最后一行可能是纯(e-s))我想可能有一些中间计算需要Monad用于其他(更好的)计算示例。虽然我们现在无法派生
Distributive
,但所有
Representable
functor都有一个默认定义:
distribute=distributeRep
Pair
Monad
实例与
Reader
不同。@danidiaz是这样吗?它看起来和我一样。@Enlico是的。这听起来像是与别人对你说的话相矛盾吗?(在我看来不是这样。)@danidiaz,在我看来也一样。@danidiaz,再说一遍,你为什么说他们看起来不一样?你能提供一个具体的例子,说明他们的行为有什么不同吗?
{-# Language DeriveAnyClass #-}
{-# Language DeriveGeneric #-}
{-# Language DeriveTraversable #-}
{-# Language DerivingVia #-}

import Control.Applicative
import Data.Distributive
import Data.Functor.Rep
import GHC.Generics

class (Applicative c, Foldable c) => Coordinates c where
    distance :: Floating a => c a -> c a -> a
    distance start end = sqrt $ sum $ fmap (^2) $ liftA2 (-) end start

data Triple a = Triple
    { triple1 :: a
    , triple2 :: a
    , triple3 :: a
    }
    deriving ( Show, Eq, Ord, Functor, Foldable, Generic1, Representable
             , Coordinates )
    deriving (Applicative, Monad) via Co Triple

instance Distributive Triple where
    distribute f = Triple (triple1 <$> f) (triple2 <$> f) (triple3 <$> f)
> distance (Triple 7 4 3) (Triple 17 6 2)
10.246950765959598
to (Pair f t) = \b -> if b then t else f

from f = Pair (f False) (f True)