首页 > 解决方案 > 在本地绑定中查找表达式的类型

问题描述

有没有办法shift通过重写下面的实例来找到下面代码中的类型?当我尝试在下面调用它时找不到它的类型是因为它是本地绑定(在 where 构造中)吗?

class CoMonad m where
  extract :: m a -> a
  (<<=) :: (m a -> b) -> m a -> m b
instance (Monoid s) => CoMonad ((->) s) where
  extract = ($ mempty)
  f <<= r = \ t -> (f . shift t) r
     where shift t rr = \ s -> rr (s <> t)

:t shift

<interactive>:1:1: error: Variable not in scope: shift

    

标签: haskell

解决方案


一种可能性是shift使用通配符给出不完整的签名:

class CoMonad m where
  extract :: m a -> a
  (<<=) :: (m a -> b) -> m a -> m b
instance (Monoid s) => CoMonad ((->) s) where
  extract = ($ mempty)
  f <<= r = \ t -> (f . shift t) r
     where
     shift :: _ 
     shift t rr = \ s -> rr (s <> t)

这将无法通过有用的错误消息进行类型检查:

<interactive>:9:15: error:
    • Found type wildcard ‘_’ standing for ‘s -> (s -> t) -> s -> t’
      Where: ‘t’ is a rigid type variable bound by
               the inferred type of shift :: s -> (s -> t) -> s -> t
               at <interactive>:10:6-36
             ‘s’ is a rigid type variable bound by
               the instance declaration
               at <interactive>:5:10-39
      To use the inferred type, enable PartialTypeSignatures
    • In the type signature: shift :: _
      In an equation for ‘&lt;<=’:
          f <<= r
            = ...
            where
                ...
      In the instance declaration for ‘CoMonad ((->) s)’
    • Relevant bindings include
        r :: s -> a (bound at <interactive>:7:9)
        f :: (s -> a) -> b (bound at <interactive>:7:3)
        (<<=) :: ((s -> a) -> b) -> (s -> a) -> s -> b
          (bound at <interactive>:7:5)

正如 Jon Purdy提醒我们的那样,部分签名也可以内联添加,作为类型注释:

(\ t -> (f . (shift :: _)) r

如果您实际上还没有添加本地绑定,则类型化的孔(_shift在下面的示例中)将以类似的方式为您提供所缺少的任何内容的推断类型。

\ t -> (f . _shift) r

推荐阅读