代码之家  ›  专栏  ›  技术社区  ›  user4035

应用函子定律

  •  1
  • user4035  · 技术社区  · 6 年前

    在线课程的练习。

    假设,对于一个标准的列表应用函子 <*> 运算符是以标准方式定义的,而 pure 改为

    pure x = [x,x]
    

    应用程序类型类将违反哪些法律?

    • 同态: 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)]
    

    然后我试着:

    同态: 纯g<*>纯x纯(gx)

    *Main> pure g <*> pure x :: MyList Integer
    MyList {getMyList = [2,2,2,2]}
    *Main> pure (g x) :: MyList Integer
    MyList {getMyList = [2,2]}
    

    身份: 纯id<*>xs xs

    *Main> pure id <*> xs :: MyList Integer
    MyList {getMyList = [1,2,1,2]}
    *Main> xs :: MyList Integer
    MyList {getMyList = [1,2]}
    

    交换: fs<*>纯x纯($x)<*>财政司司长

    *Main> fs <*> pure x
    [2,3]
    *Main> pure ($ x) <*> fs
    [2,3]
    

    应用函子: g<$>纯g<*>xs

    *Main> g <$> xs
    MyList {getMyList = [2,4]}
    *Main> pure g <*> xs
    MyList {getMyList = [2,4,2,4]}
    

    组成: ()<$>美国<*>vs<*>xs美国<*>(vs<*>xs)

    *Main> (.) <$> us <*> vs <*> xs
    MyList {getMyList = [6,12]}
    *Main> us <*> (vs <*> xs)
    MyList {getMyList = [6,12]}
    

    作文不应该被违反,因为 纯净的 这里不用。

    看来同态、恒等式和应用函子都不起作用。但当我在课程中选择它们时,它表明答案是错误的。那么,谁是傻瓜:我还是这门课程的作者?

    0 回复  |  直到 6 年前
        1
  •  2
  •   K. A. Buhr    6 年前

    根据@DavidFletcher的评论,使用您的代码,我看到交换测试的不同输出:

    > fs <*> pure x
    MyList {getMyList = [2,2,3,3]}
    > pure ($ x) <*> fs
    MyList {getMyList = [2,3,2,3]}
    

    所以你可能想再检查一遍。

    推荐文章