Tôi đang cố gắng làm câu hỏi này từ bài tập về nhà của tôi:
Cho tùy ý
foo :: [[a]] -> ([a], [a])
, viết ra một luật mà hàmfoo
thỏa mãn, liên quan đếnmap
danh sách và cặp.
Một số bối cảnh: Tôi là sinh viên năm thứ nhất đang theo học một khóa lập trình chức năng. Trong khi khóa học khá giới thiệu, giảng viên đã đề cập đến nhiều điều ngoài giáo trình, trong số đó là các định lý miễn phí. Vì vậy, sau khi cố gắng đọc báo Wadler, tôi cho rằng, concat :: [[a]] -> [a]
với luật pháp map f . concat = concat . map (map f)
trông có liên quan đến vấn đề của tôi, kể từ khi chúng ta phải có foo xss = (concat xss, concat' xss)
nơi concat
và concat'
bất kỳ chức năng của loại [[a]] -> [a]
. Thế là foo
thỏa mãn bimap (map f, map g) . foo = \xss -> ((fst . foo . map (map f)) xss, (snd . foo . map (map g)) xss)
.
Đã 'luật' này dường như quá dài để chính xác, và tôi cũng không chắc về logic của mình. Vì vậy, tôi đã nghĩ đến việc sử dụng một trình tạo định lý miễn phí trực tuyến , nhưng tôi không hiểu ý lift{(,)}
nghĩa của nó là gì :
forall t1,t2 in TYPES, g :: t1 -> t2.
forall x :: [[t1]].
(f x, f (map (map g) x)) in lift{(,)}(map g,map g)
lift{(,)}(map g,map g)
= {((x1, x2), (y1, y2)) | (map g x1 = y1) && (map g x2 = y2)}
Làm thế nào tôi nên hiểu đầu ra này? Và làm thế nào tôi nên rút ra luật cho chức năng foo
đúng?
(\(a,b) -> (map f a, map f b)) . foo = foo . map (map f)