2012-11-27 33 views
5

Có thể xác định toán tử ++ của riêng tôi cho một kiểu dữ liệu tùy chỉnh trong Haskell không?Toán tử concat (++) tùy chỉnh trong haskell

tôi có:

data MyType = MyType [String] 

và tôi muốn xác định điều hành nối của riêng tôi như:

instance ? MyType where 
    (MyType x) ++ (MyType y) = MyType (x ++ y) 

tôi dường như không thể tìm ra tên của lớp dụ bất cứ nơi nào.

Trả lời

13

Nếu bạn không nhấn mạnh vào gọi các nhà điều hành (++),

import Data.Monoid 

instance Monoid MyType where 
    (MyType x) `mappend` (MyType y) = MyType (x ++ y) 
    mempty = MyType [] 

Sau đó, bạn có thể sử dụng

(<>) :: Monoid m => m -> m -> m 

mà là một bí danh cho mappend (Tôi nghĩ rằng nó đã là một thành viên lớp loại, nhưng nó không phải là : /). Danh sách hava a Monoid trường hợp trong đó mappend(++), do đó sẽ làm những gì bạn mong muốn. Các ví dụ Monoid cũng cung cấp cho bạn

mconcat :: Monoid m => [m] -> m 

mà bạn có thể sử dụng để nối một danh sách các MyType s.

+0

đó là sự khác biệt giữa một lập trình viên chuyên nghiệp và thời gian rảnh - biết rằng có kiểu chữ "Monoid'. – epsilonhalbe

+0

Toán tử <> có được định nghĩa giống như toán tử ++ cho các danh sách không? –

+0

@WesleyTansey Vâng, nhưng tôi vừa kiểm tra và có vẻ như đó chưa phải là một thành viên trong các phiên bản GHC được phát hành, vì vậy tôi phải sửa một chút giải pháp của mình. –

4

đơn giản nhất nó sẽ làm

import Prelude hiding ((++)) 
import qualified Prelude as P 

data MyType = MyType [String] 

class PlusAble a where 
    infixr 5 ++ 
    (++) :: a -> a -> a 

instance PlusAble MyType where 
    (MyType x) ++ (MyType y) = MyType (x P.++ y) 

-- EDIT: 
instance PlusAble [a] where 
    x ++ y = x P.++ y 
+0

Giải pháp này dường như gây ra cho tôi các vấn đề khiến tất cả các hoạt động ++ khác trở nên mơ hồ. –

+0

Tôi nghĩ rằng bạn phải thêm một thể hiện cho các danh sách - tôi đã thêm điều này vào phần chỉnh sửa – epsilonhalbe

3

(++) toán tử không thuộc bất kỳ loại loại nào. Bạn có thể dễ dàng kiểm tra điều này:

$ ghci 
Prelude> :info (++) 
(++) :: [a] -> [a] -> [a] -- Defined in `GHC.Base' 
infixr 5 ++ 

Vì vậy, nó chỉ là chức năng đơn giản được xác định trong mô-đun GHC.Base. Bạn có thể ẩn nó và xác định riêng của bạn:

import Prelude hiding ((++)) 
import qualified Prelude -- to get hidden (++) as Prelude.(++) 

-- your brand new (++) 
infixr 5 ++ 
(MyType x) ++ (MyType y) = MyType (x Prelude.++ y) 
Các vấn đề liên quan