Tôi đang làm việc qua 20 Intermediate Haskell Exercises vào lúc này, đây là một bài tập khá thú vị. Nó liên quan đến việc thực hiện các trường hợp khác nhau của typeclasses Functor
và Monad
(và các chức năng mất Functor
s và Monad
s làm đối số) nhưng với các tên dễ thương như Furry
và Misty
để che giấu những gì chúng tôi đang làm (làm cho một số mã thú vị).Sơ đồ tổng quát để viết một hàm theo kiểu pointfree là gì?
Tôi đã cố gắng thực hiện một số điều này theo kiểu không có điểm, và tôi tự hỏi liệu có một phương án chung để chuyển định nghĩa point-ful (?) Thành định nghĩa không điểm. Ví dụ, đây là typeclass cho Misty
:
class Misty m where
unicorn :: a -> m a
banana :: (a -> m b) -> m a -> m b
(các chức năng unicorn
và banana
là return
và >>=
, trong trường hợp nó không rõ ràng) và đây là thực hiện của tôi apple
(tương đương với flip ap
):
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple x f = banana (\g -> banana (unicorn . g) x) f
Các phần sau của bài tập có bạn thực hiện các phiên bản liftM
, liftM2
vv. Dưới đây là các giải pháp của tôi:
appleTurnover :: (Misty m) => m (a -> b) -> m a -> m b
appleTurnover = flip apple
banana1 :: (Misty m) => (a -> b) -> m a -> m b
banana1 = appleTurnover . unicorn
banana2 :: (Misty m) => (a -> b -> c) -> m a -> m b -> m c
banana2 f = appleTurnover . banana1 f
banana3 :: (Misty m) => (a -> b -> c -> d) -> m a -> m b -> m c -> m d
banana3 f x = appleTurnover . banana2 f x
banana4 :: (Misty m) => (a -> b -> c -> d -> e) -> m a -> m b -> m c -> m d -> m e
banana4 f x y = appleTurnover . banana3 f x y
Bây giờ, banana1
(tương đương liftM
hoặc fmap
) Tôi đã có thể triển khai theo kiểu không có điểm, theo định nghĩa phù hợp là appleTurnover
. Nhưng với ba hàm khác tôi đã phải sử dụng các tham số.
Câu hỏi của tôi là: có công thức để chuyển định nghĩa như thế này thành các định nghĩa không điểm?
Nó kết nối với việc loại bỏ trừu tượng bạn làm để biến các biểu thức tính toán lambda thành các combinators. Bạn cũng có thể muốn kiểm tra công cụ [pointfree] độc lập (http://hackage.haskell.org/package/pointfree) (cũng có sẵn dưới dạng '@ pl' trong [lambdabot] (http://www.haskell.org)/haskellwiki/Lambdabot)). – ehird
[Một cuộc thảo luận liên quan mà tôi đã có với một người bạn ngày hôm kia] (https://gist.github.com/1507246). Bạn có thể thấy nó hấp dẫn. – missingfaktor