Haskell中最短的a-> b->(a-> b)函数


19

我在测试中遇到以下问题:

f用以下类型编写一个函数a -> b -> (a -> b)a并且b从任何意义上讲都不应受到限制,代码越短越好。

我想出了f a b = \x -> snd ([a,x],b)。你能找到些小东西吗?

目前获胜者是: f _=(.f).const


如果允许使用更通用的类型:f = const const
hammar 2014年

@hammar:或者f _ b _ = b,但是,考虑到问题的解决,我怀疑一个更普遍的类型不是允许的。
Tikhon Jelvis,2014年

6
如果允许使用更通用的类型,为什么不f = id呢?
汤姆·埃利斯

7
实际上,如果允许使用更通用的类型,那么这f = f是一个解决方案,所以我想类型上的条件非常重要!
汤姆·埃利斯

2
不允许使用更通用的类型,您的假设是正确的。
Radu Stoenescu 2014年

Answers:


11

通过取消右侧的匿名函数,可以缩小您的示例:

f a b x = snd ([a,x],b)

a -> b -> a -> b是可行的,因为类型与a -> b -> (a -> b)Haskell中的等效。


4
稍短的修改:f a b x = snd (f x,b)
Ed'ka

5

该功能f _=(.f).const实际上是一种更普遍的类型比f :: a -> b -> (a -> b),即f :: a -> b -> (c -> b)。如果没有给出类型签名,则类型推断系统会推断类型为f :: a -> b -> (a -> b),但是如果您包含f :: a -> b -> (c -> b)具有完全相同定义的类型签名,Haskell将对其进行编译而不会出现问题,并将报告f的部分应用的一致类型。在这种情况下,类型推断系统比类型检查系统更严格的原因可能很深,但是我不了解足够的类别理论,无法给出为什么会这样的原因。如果您不满意,欢迎您自己尝试。


可能类似的情况f a b = f a aa -> a -> b尽管符合类型,但推断为类型a -> b -> c。这是因为如果f没有给定类型,那么它只能单态使用。
自豪的haskeller 2014年

我认为这并不重要
骄傲的haskeller 2014年

4

鉴于ScopedTypeVariables,我想到了这个:

f (_::a) b (_::a) = b

如果您同时缩小我和您的功能,我的头发会短一些:

f(_::a)b(_::a)=b
f a b x=snd([a,x],b)

当然,您可能不被允许依赖ScopedTypeVariables:P。


3
这不如f _=(.f).const由于Sassa NF)短。这也不需要ScopedTypeVariables
不再转动逆时针

嗯,我最初以为这需要列出第一个和第三个参数...
克里斯·泰勒

@ChrisTaylor:头脑中有太多OCaml吗?:)
Tikhon Jelvis,2014年

哈,一定是!;)
克里斯·泰勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.