违反适用函子法
Applicative functor laws violation
来自在线课程的练习题。
假设,对于标准列表 Applicative functor,<*>
运算符以标准方式定义,而 pure
更改为
pure x = [x,x]
Applicative typeclass 会违反哪些规则?
- 同态:
pure g <*> pure x ≡ pure (g x)
- 身份:
pure id <*> xs ≡ xs
- 交汇处:
fs <*> pure x ≡ pure ($ x) <*> fs
- 应用函子:
g <$> xs ≡ pure g <*> xs
- 组成:
(.) <$> us <*> vs <*> xs ≡ us <*> (vs <*> xs)
我创建了以下文件:
newtype MyList a = MyList {getMyList :: [a]}
deriving Show
instance Functor MyList where
fmap f (MyList xs) = MyList (map f xs)
instance Applicative MyList where
pure x = MyList [x,x]
MyList gs <*> MyList xs = MyList ([g x | g <- gs, x <- xs])
fs = MyList [\x -> 2*x, \x -> 3*x]
xs = MyList [1,2]
x = 1
g = (\x -> 2*x)
us = MyList [(\x -> 2*x)]
vs = MyList [(\x -> 3*x)]
然后我尝试了:
同态:pure g <*> pure x ≡ pure (g x)
*Main> pure g <*> pure x :: MyList Integer
MyList {getMyList = [2,2,2,2]}
*Main> pure (g x) :: MyList Integer
MyList {getMyList = [2,2]}
身份:pure id <*> xs ≡ xs
*Main> pure id <*> xs :: MyList Integer
MyList {getMyList = [1,2,1,2]}
*Main> xs :: MyList Integer
MyList {getMyList = [1,2]}
交汇处:fs <*> pure x ≡ pure ($ x) <*> fs
*Main> fs <*> pure x
[2,3]
*Main> pure ($ x) <*> fs
[2,3]
应用函子:g <$> xs ≡ pure g <*> xs
*Main> g <$> xs
MyList {getMyList = [2,4]}
*Main> pure g <*> xs
MyList {getMyList = [2,4,2,4]}
作文:(.) <$> us <*> vs <*> xs ≡ us <*> (vs <*> xs)
*Main> (.) <$> us <*> vs <*> xs
MyList {getMyList = [6,12]}
*Main> us <*> (vs <*> xs)
MyList {getMyList = [6,12]}
作文不应该被违反,因为这里没有使用pure
。
同态、恒等式和应用函子好像不行。但是当我在课程中select他们时,它说答案是错误的。那么,谁是傻瓜:我还是课程作者?
根据@DavidFletcher 的评论,使用您的代码,我看到交换测试的不同输出:
> fs <*> pure x
MyList {getMyList = [2,2,3,3]}
> pure ($ x) <*> fs
MyList {getMyList = [2,3,2,3]}
所以你可能想仔细检查那个。
来自在线课程的练习题。
假设,对于标准列表 Applicative functor,<*>
运算符以标准方式定义,而 pure
更改为
pure x = [x,x]
Applicative typeclass 会违反哪些规则?
- 同态:
pure g <*> pure x ≡ pure (g x)
- 身份:
pure id <*> xs ≡ xs
- 交汇处:
fs <*> pure x ≡ pure ($ x) <*> fs
- 应用函子:
g <$> xs ≡ pure g <*> xs
- 组成:
(.) <$> us <*> vs <*> xs ≡ us <*> (vs <*> xs)
我创建了以下文件:
newtype MyList a = MyList {getMyList :: [a]}
deriving Show
instance Functor MyList where
fmap f (MyList xs) = MyList (map f xs)
instance Applicative MyList where
pure x = MyList [x,x]
MyList gs <*> MyList xs = MyList ([g x | g <- gs, x <- xs])
fs = MyList [\x -> 2*x, \x -> 3*x]
xs = MyList [1,2]
x = 1
g = (\x -> 2*x)
us = MyList [(\x -> 2*x)]
vs = MyList [(\x -> 3*x)]
然后我尝试了:
同态:pure g <*> pure x ≡ pure (g x)
*Main> pure g <*> pure x :: MyList Integer
MyList {getMyList = [2,2,2,2]}
*Main> pure (g x) :: MyList Integer
MyList {getMyList = [2,2]}
身份:pure id <*> xs ≡ xs
*Main> pure id <*> xs :: MyList Integer
MyList {getMyList = [1,2,1,2]}
*Main> xs :: MyList Integer
MyList {getMyList = [1,2]}
交汇处:fs <*> pure x ≡ pure ($ x) <*> fs
*Main> fs <*> pure x
[2,3]
*Main> pure ($ x) <*> fs
[2,3]
应用函子:g <$> xs ≡ pure g <*> xs
*Main> g <$> xs
MyList {getMyList = [2,4]}
*Main> pure g <*> xs
MyList {getMyList = [2,4,2,4]}
作文:(.) <$> us <*> vs <*> xs ≡ us <*> (vs <*> xs)
*Main> (.) <$> us <*> vs <*> xs
MyList {getMyList = [6,12]}
*Main> us <*> (vs <*> xs)
MyList {getMyList = [6,12]}
作文不应该被违反,因为这里没有使用pure
。
同态、恒等式和应用函子好像不行。但是当我在课程中select他们时,它说答案是错误的。那么,谁是傻瓜:我还是课程作者?
根据@DavidFletcher 的评论,使用您的代码,我看到交换测试的不同输出:
> fs <*> pure x
MyList {getMyList = [2,2,3,3]}
> pure ($ x) <*> fs
MyList {getMyList = [2,3,2,3]}
所以你可能想仔细检查那个。