【问题标题】:Manual derivation of the type for `f1 x xs = (filter . (<)) x xs`手动推导 `f1 x xs = (filter . (<)) x xs` 的类型
【发布时间】:2014-06-13 04:33:15
【问题描述】:

我想手动导出类型:

f1 x xs = (filter . (&lt;)) x xs

我们第一次看到x,所以:

x :: t1

那么(&lt;)就有这个类型:

(<) :: Ord a1 => a1 -> a1 -> Bool

如果可以统一以下类型,我们只能说(&lt; x)

t1  ~  a1

然后

x :: a1

所以

(<x) :: Ord a1 => a1 -> Bool

过滤器有这种类型

filter :: (a2 -> Bool) -> [a2] -> [a2]

第一次见xs,所以:

xs :: t2

如果可以统一以下类型,我们只能说(filter . (&lt;)) x xs

a1 -> Bool ~ a2 -> Bool
t2  ~ [a2]

所以我得到了 f1 :: (a2 -&gt; Bool) -&gt; [a2] -&gt; [a2],与 filter 相同的类型,而正确的类型是 Ord a =&gt; a -&gt; [a] -&gt; [a](询问 GHCi)。

有什么帮助吗?

【问题讨论】:

    标签: haskell types ghci unification


    【解决方案1】:

    约束

    a1 -> Bool ~ a2 -> Bool
    

    可以分解为

    a1 ~ a2
    

    显然是真的

    Bool ~ Bool
    

    所以你有a1 ~ a2。您已经知道xa1xs[a2],并且感谢filter,结果类型是[a2]。因此,您最终会得到:

    f1 :: Ord a2 => a2 -> [a2] -> [a2]
    

    (不要忘记从(&lt;)得到的类约束a1。)

    【讨论】:

      【解决方案2】:

      我们可以以自上而下的方式处理给定的表达式。这样就无需猜测去哪里了,推导完全机械地发生,错误空间最小:

      f1    x   xs = (filter . (<)) x xs
      f1    x   xs :: c                        (filter . (<)) x xs :: c
      f1    x :: b -> c                        xs :: b
      f1 :: a -> b -> c                        x  :: a 
      
      (filter .  (<)) x      xs  :: c
      filter    ((<)  x)  ::  b  -> c          c ~ [d] , b ~ [d]
      filter :: (d->Bool) -> [d] -> [d]        (<) x :: d -> Bool
      
      (<) :: (Ord a) => a -> a -> Bool
      (<)               x :: d -> Bool         a ~ d , (Ord a)
      
      f1  :: (Ord a) => a -> [a] -> [a]
      

      解决这个问题的另一种方法是注意可以在f1 的定义中执行eta 减少

      f1    x   xs = (filter . (<)) x xs
      f1           = (.) filter (<)
      
      (.) :: (   b      ->     c     ) -> (           a ->   b      ) -> (a->c)
      (.)             filter                           (<)            ::   t1
      (.) :: ((d->Bool) -> ([d]->[d])) -> ((Ord a) => a -> (a->Bool)) ->   t1
      
              b ~ d -> Bool , c ~ [d] -> [d] , t1 ~ a -> c , (Ord a)
              b ~ a -> Bool
              -------------
                  d ~ a
      
      f1 :: t1 ~ (Ord a) => a -> c 
               ~ (Ord a) => a -> [d] -> [d]
               ~ (Ord a) => a -> [a] -> [a]
      

      当然,我们在类型中使用箭头的右关联性:a -&gt; b -&gt; c 实际上是 a -&gt; (b -&gt; c)

      我们也使用a general scheme for type derivations

      f    x    y    z :: d
      f    x    y :: c -> d      , z :: c
      f    x :: b -> c -> d      , y :: b
      f :: a -> b -> c -> d      , x :: a
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-21
        • 1970-01-01
        • 1970-01-01
        • 2017-10-29
        • 2014-03-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多