首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >手动派生类型为‘f1xxs=(过滤器。(<))

手动派生类型为‘f1xxs=(过滤器。(<))
EN

Stack Overflow用户
提问于 2014-04-27 18:37:29
回答 2查看 159关注 0票数 0

我想手动导出以下类型:

f1 x xs = (filter . (<)) x xs

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

代码语言:javascript
复制
x :: t1

然后,(<)具有以下类型:

代码语言:javascript
复制
(<) :: Ord a1 => a1 -> a1 -> Bool

只有当可以统一下列类型时,我们才能说(< x)

代码语言:javascript
复制
t1  ~  a1

然后

代码语言:javascript
复制
x :: a1

所以

代码语言:javascript
复制
(<x) :: Ord a1 => a1 -> Bool

过滤器具有这种类型

代码语言:javascript
复制
filter :: (a2 -> Bool) -> [a2] -> [a2]

第一次看到xs,所以:

代码语言:javascript
复制
xs :: t2

只有当可以统一下列类型时,我们才能说(filter . (<)) x xs

代码语言:javascript
复制
a1 -> Bool ~ a2 -> Bool
t2  ~ [a2]

因此,当正确的类型是f1 :: (a2 -> Bool) -> [a2] -> [a2] (询问GHCi)时,我得到了与filter相同的类型的Ord a => a -> [a] -> [a]

有什么帮助吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-27 18:52:22

约束

代码语言:javascript
复制
a1 -> Bool ~ a2 -> Bool

可以分解成

代码语言:javascript
复制
a1 ~ a2

显然是真的

代码语言:javascript
复制
Bool ~ Bool

所以你有a1 ~ a2了。您已经知道xa1xs[a2],由于filter,结果类型是[a2]。因此,您的结果是:

代码语言:javascript
复制
f1 :: Ord a2 => a2 -> [a2] -> [a2]

(不要忘记a1(<)获得的类约束。)

票数 6
EN

Stack Overflow用户

发布于 2014-04-27 21:29:02

我们可以用自顶向下的方式处理给定的表达式。这样就不需要猜测哪里去了,推导完全是机械的,只有最小的出错空间:

代码语言:javascript
复制
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减少操作。

代码语言:javascript
复制
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 -> b -> c实际上是a -> (b -> c)

我们还使用a general scheme for type derivations

代码语言:javascript
复制
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
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23327370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档