它的反转似乎是可能的。
由于我认为列表是产品而->
是取幂,
(a*a*a...)^r = (a^r)*(a^r)....
既然我们可以定义逆[a->r] -> a -> [r]
,那么可以定义它吗?
答案 0 :(得分:8)
[a] ≅ a*a*...
仅适用于无限列表。对于这些,您所请求的功能实际上非常简单,尽管天真的实现效率不高:
type InfiList = []
unwind :: (r -> InfiList a) -> InfiList(r -> a)
unwind f = [ \x -> f x !! n | n <- [0..] ]
实际上,[a] ≅ 1 + a * (1 + a * (1 + ...))
;这里的幂律不起作用。
答案 1 :(得分:4)
如果您愿意修复功能列表的大小,那么它就可以正常工作。
dn :: [r -> a] -> (r -> [a])
dn fns r = map ($ r)
up :: Int -> (r -> [a]) -> [r -> a]
up n f = tabulate n (\i r -> f' r !! i)
where
f' = cycle . f
tabulate n f = map f [0..n-1]
现在我们可以将up
作为&#34;类型的&#34;如果我们在一些长度信息中移动,那么dn
的左逆...:
id1 :: [r -> a] -> [r -> a]
id1 ls = up (length ls) (dn ls)
它可以是&#34;&#34;&#34;&#34;&#34;如果我们神奇地知道(a)每个dn
结果列表r
的长度是相同的,并且(b)我们知道该长度(称为{{1),则[a]
的右逆下面)
magic
此答案基本上等同于id2 :: (a -> [b]) -> a -> [b]
id2 f = dn . up magic
对copumpkin
的答案的评论,但不是使用类型I来传递(固定)长度信息手动。如果您稍微使用leftroundabout
和up
,您就会明白为什么这种事情一般不适用于列表。
答案 2 :(得分:1)
直观地说,如果事先不知道列表的长度,这是不可能的。
这是因为类型r -> [a]
大致代表以下内容:
r
n
(包括无限)n
a
值列表
醇>
举个例子,拿
replicateA :: Int -> [Char] -- r = Int , a = Char
replicateA 0 = []
replicateA n = 'A' : replicate (n-1)
相比之下,类型[r -> a]
大致代表以下内容:
n
(包括无限)n
元素中:
r
a
这里的关键事实是,在知道r
输入之前,必须在之前生成列表的长度。通常,这不能完成,因为长度可以取决于r
,正如上面的replicateA
示例所示。