ClassyPrelude có hai chức năng bản đồ, cụ thể là:Lý do cho hai chức năng bản đồ riêng biệt trong ClassyPrelude
map
omap
map
công trình trên bất kỳ Functor
. Tuy nhiên, những thứ như Text
không phải là functors vì chúng không phải là các container chung. Nghĩa là, chúng không thể chứa bất kỳ loại nào, không giống như một danh sách. Như có thể thấy trong đoạn mã sau:
module Main where
import Prelude()
import ClassyPrelude
import qualified Data.Text as T
import Data.Char as C
main = do
let l = [1,2,3] :: [Int]
let t = (T.pack "Hello")
let m = Just 5
print $ map (*2) l
print $ map (*2) m
print $ omap C.toUpper t
return()
Thông báo người ta phải sử dụng omap
để đối phó với Text
. Vì map
yêu cầu loại là Functor
, map f text
không thành công. Vấn đề là, tôi thấy dễ dàng để xác định lại map
để hoạt động cho cả hai cuộc gọi. Đây là mã:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverlappingInstances #-}
module Main where
import Prelude hiding (map)
import qualified Data.Text as T
import Data.Char as C
import Control.Monad (Functor)
import qualified Data.Vector.Unboxed as U
class CanMap a b where
type Element a :: *
type Container a b :: *
map :: (Element a -> b) -> a -> Container a b
instance (Functor f) => CanMap (f a) b where
type Element (f a) = a
type Container (f a) b = f b
map = fmap
instance CanMap T.Text Char where
type Element T.Text = Char
type Container T.Text Char = T.Text
map = T.map
instance (U.Unbox a, U.Unbox b) => CanMap (U.Vector a) b where
type Element (U.Vector a) = a
type Container (U.Vector a) b = U.Vector b
map = U.map
main = do
let l = [1,2,3] :: [Int]
let m = Just 5
let t = (T.pack "Hello")
let u = U.generate 3 id
print $ map (*2) l
print $ map (*2) m
print $ map C.toUpper t
print $ map (*2) u
return()
Tất cả những gì cần thiết là thêm trường hợp vào CanMap cho bất kỳ thùng chứa đơn lẻ nào. ClassyPrelude đã làm điều này anyway với "omap" trong mô-đun Data.MonoTraversable. Tôi nghi ngờ tuy nhiên có một lý do chính đáng tôi bỏ lỡ về lý do tại sao nên có hai chức năng bản đồ riêng biệt để đối phó với những tình huống thay thế này, nhưng tôi tự hỏi đó là những gì.