2015-09-14 12 views
6

Giả sử tôi cóHai typeclasses có thể có cùng tên phương thức?

class Foo a where 
    (++=) :: a -> a -> a 
    cool :: (a -> b -> b) -> a -> b 

và muốn làm cho

class Bar a where 
    (++=) :: (a -> b) -> a -> b 
    magic :: a -> b 

trong đó có một tên phương pháp chồng chéo, (++=). Có cách nào tôi có thể làm điều này?

+0

Trong OOP, các phương thức cùng tên được cho phép vì loại đối tượng 'this' này có thể phân biệt giữa chúng. Trong Haskell, không có 'này' xung quanh: các phương thức cho' Foo a' không ngầm lấy một đối số 'a'. Ngay cả khi họ đã làm, loại suy luận sẽ trở nên khá phức tạp, vì bạn cần phải tính toán loại 'this' _before_ bạn có thể biết loại phương thức. Trong hầu hết các ngôn ngữ OOP, không có hoặc ít suy luận kiểu w.r.t. ngôn ngữ chức năng, vì vậy đây không phải là vấn đề ở đó. – chi

+2

Ngoài ra, đây là những hàm không phải là phương thức, chính xác. –

+4

@Erik Alik: Trên thực tế, mặc dù nó rất khác với khái niệm OO, [từ 'phương pháp' về mặt kỹ thuật là đúng] (https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3) . –

Trả lời

2

Câu hỏi này có một tinh tế "không nhưng có" loại câu trả lời, mà đòi hỏi phải đi sâu vào ba khái niệm:

  1. tên Qualified vs tên không đủ tiêu chuẩn
  2. Modules và nhập khẩu
  3. Aliasing

Điểm 1: mọi định nghĩa trong Haskell đều có tên ngắn, không đủ tiêu chuẩn như map và tên dài, đủ điều kiện như Data.List.map.

Điểm 2: khi bạn nhập mô-đun vào mô-đun khác, bạn có thể thực hiện nhập đủ điều kiện hoặc không đủ tiêu chuẩn. Khi bạn sử dụng nhập không đủ tiêu chuẩn, tên của mô-đun nước ngoài mà bạn mang vào sẽ được đặt bí danh dưới tên ngắn của chúng. Khi bạn làm một nhập khẩu đủ điều kiện, họ sẽ chỉ có sẵn dưới một cái tên được sửa đổi:

import qualified Data.Map as Map 

Bây giờ trong module, nơi này xuất hiện, các Data.Map.map chức năng có thể nhìn thấy dưới bí danh Data.map.

Điểm thứ ba: điều này có nghĩa là mọi định nghĩa Haskell đều có tên đủ điều kiện được xác định bằng tên ngắn và mô-đun được xác định, nhưng cũng không đủ điều kiện hoặc một phần bí danh đủ điều kiện trong mỗi mô-đun được nhập.

Bây giờ, câu hỏi của bạn có hai câu trả lời:

  1. Hai lớp học khác nhau không có thể có phương pháp mà chia sẻ cùng một đầy đủ tên. Vì vậy, nếu bạn xác định các lớp học FooBar trong cùng một mô-đun, điều đó sẽ không thành công.
  2. Hai lớp khác nhau có thể có các phương thức có cùng tên không đủ điều kiện, miễn là tên đủ điều kiện của chúng khác nhau - tức là chúng được xác định trong các mô-đun khác nhau. Tuy nhiên, để sử dụng cả hai trong một mô-đun máy khách, bạn sẽ cần ít nhất một lần nhập đủ điều kiện để các bí danh từ quá trình nhập không xung đột.
+1

Trong ví dụ của bạn, bạn có nghĩa là' Bản đồ .map' hoặc 'nhập Dữ liệu đủ điều kiện.Mã dữ liệu', phải không? – suffi

4

Không, bạn không thể, ít nhất trong cùng một mô-đun. Bạn có thể khai báo class Fooclass Bar trong hai mô-đun khác nhau và nhập từng mô-đun vào cùng một tệp, nhưng bạn vẫn sẽ phải qualify ít nhất một trong các mục nhập đó để tránh xung đột.

+8

Vì vậy, đó là "có, bạn có thể, nếu ..." không "không bạn không thểl :) –

+2

@ErikAllik Họ theo nghĩa đen không thể có cùng tên. Đủ điều kiện khiến họ có tên khác nhau. –

0

Sau đây biên dịch mà không cần bất kỳ lỗi:

Main.hs:

module Main where 

import qualified Foo 
import Bar 

instance Foo.Foo Char where 
    c1 ++= c2 = c1 

instance Bar Char where 
    f ++= c = f c 

main = do 
    putStrLn $ [ 'a' Foo.++= 'b' ] 

Foo.hs:

module Foo where 

class Foo a where 
    (++=) :: a -> a -> a 

Bar.hs:

module Bar where 

class Bar a where 
    (++=) :: (a -> b) -> a -> b 

Vì vậy, nói cách khác, chúng ta không cần phải tham khảo ++= sử dụng tên đầy đủ của nó bên trong khai báo cá thể, nhưng khi được sử dụng bên trong main, chúng tôi cần chỉ định số nào là ++= mà chúng ta đang nói đến. Trong tuyên bố cá thể, chúng tôi đã xác định phạm vi cho ++=, trong khi main sẽ không biết cái nào được nhắc đến, nếu chúng tôi đã sử dụng nhập không đủ tiêu chuẩn. Do đó, nếu tất cả những gì chúng ta muốn làm là xác định các cá thể lớp, thì chúng ta sẽ không cần nhập khẩu đủ điều kiện.

Các vấn đề liên quan