2011-11-17 31 views
7

Có ai biết nếu có một hàm trong Haskell mà làm điều gì đó như thế này:Chuyển đổi một chuỗi đến một Loại Constructor trong Haskell

"Int" -> Int 

"String" -> String 

"Bool" -> Bool 

tức. nó lấy một biểu diễn chuỗi của một tên hàm dựng, và chuyển đổi nó thành một hàm tạo kiểu thực, cả trong một biểu thức và trong một mẫu.

chỉnh sửa: Mục tiêu tổng thể của tôi là để đơn giản hóa một cái gì đó như:

transExp (Add exp1 exp2) vars 
    = transExp exp1 vars ++ transExp exp2 vars ++ [IAdd] 

transExp (Sub exp1 exp2) vars 
    = transExp exp1 vars ++ transExp exp2 vars ++ [ISub] 

Into một mô hình phù hợp nhất, vì vậy về cơ bản chuyển đổi Add or Sub thành một chuỗi, thêm một chữ "I" vào phía trước, và chuyển đổi nó trở lại một loại.

+3

Điều này có thể thực hiện được không? Không phải là loại khái niệm biên dịch thời gian sao? Bạn sẽ tìm kiếm loại chức năng nào? –

+0

Tôi không biết liệu điều này là có thể hay không, tôi cho rằng nó sẽ có kiểu String -> a, nhưng tôi thực sự không chắc chắn ... – Jack

+0

Hãy xem mẫu haskell sau đó. Ngoài ra 'IAdd' không phải là một kiểu mà là một hàm tạo kiểu - đó là gây hiểu nhầm. – nponeccop

Trả lời

10

Có một cách tốt hơn để cấu trúc lại mã của bạn ở đây mà không bất kỳ mẫu Haskell hoặc shenanigans phản ánh bằng cách đơn giản tham gia AddSub bạn trường hợp thành một:

data BinOp = Add | Sub | ... 

data Expr = ... 
      | BinOp BinOp Expr Expr 
      | ... 

transExp (BinOp op exp1 exp2) vars 
    = transExp exp1 vars ++ transExp exp2 vars ++ [transOp op] 
... 

transOp Add = IAdd 
transOp Sub = ISub 

Bằng cách này, chúng ta đang sử dụng các kiểu dữ liệu để thể hiện trực tiếp thực tế là các toán tử nhị phân có liên quan và do đó có các bản dịch tương tự. Bạn vẫn có thể khớp mẫu trên BinOp Add exp1 exp2 nếu bạn muốn tạo một trường hợp đặc biệt để thêm vào một nơi nào đó.

+0

Giải pháp tuyệt vời - ít nhiều hacky hơn những gì tôi nghĩ. Cảm ơn bạn rất nhiều :) – Jack

+0

Đó là thanh lịch hơn nhiều. Cảm ơn bạn đã nhắc nhở rằng nó giúp thu nhỏ lại và có chế độ xem rộng hơn. –

2

Trong bối cảnh nào? Có mẫu Haskell và Data.Typeable, nhưng đối với câu trả lời thực sự hữu ích, bạn cần cung cấp thêm chi tiết.

0

Vâng, đây là vấn đề.

"String" -> String 

Đó là vô nghia trong Haskell-đất, vì "String" là một giá trị nhưng String là một loại. Vì vậy, bạn có thể thử điều này:

String -> a 

Điều này không làm những gì bạn muốn. Bạn nên học cách đọc chữ ký, vì nếu bạn không thể đọc chữ ký, bạn sẽ bị tàn tật nặng nề tại Haskell. Loại trên có nghĩa là "Hãy cho tôi một chuỗi và tôi có thể cung cấp cho bạn giá trị của bất kỳ loại nào bạn yêu cầu". Có một chức năng trong khúc dạo đầu với chữ ký này, nó được gọi là error, mà không phải là những gì bạn muốn.

Nghe có vẻ như bạn muốn một cái gì đó dọc theo những dòng:

String -> TypeRep 

Xin lỗi, không có chức năng như vậy. TypeRep không khởi tạo lớp Read.

Bạn là gì thực sự là đang cố gắng làm gì ở đây? Nếu bạn cho chúng tôi biết bạn đang thực sự cố gắng làm gì, chúng tôi có thể giúp bạn giải quyết vấn đề đó hơn là cố gắng giúp đỡ về vấn đề này.

+0

Anh ấy không nói về tên kiểu mà là về các nhà xây dựng kiểu. Anh ta chỉ muốn tạo ra một số giá trị và các mẫu phù hợp từ các chuỗi để tránh boilerplate. – nponeccop

+2

@nponeccop: Việc trả lời câu hỏi sau khi câu hỏi thay đổi không chính xác. Doanh nghiệp này về các nhà thầu là hoàn toàn mới. –

0

Bạn không thể làm điều đó, bởi vì chuỗi là dữ liệu thời gian chạy và các loại phải được giải quyết hoàn toàn tại thời gian biên dịch. Điều tốt nhất bạn có thể có thể làm với ví dụ của bạn là một hàm helper để loại bỏ một số trong những sự trùng lặp:

helper exp1 exp2 vars op = transExp exp1 vars ++ transExp exp2 vars ++ [op] 
transExp (Add exp1 exp2) vars = helper exp1 exp2 vars IAdd 
transExp (Sub exp1 exp2) vars = helper exp1 exp2 vars ISub 

Nhưng điều này có thể không thực sự là rất hữu ích trong dài hạn, tùy thuộc vào có bao nhiêu trường hợp mà bạn có.

Nói chung, đối sánh mẫu là thứ chạy chống lại cấu trúc kiểu, vì vậy nó phải được viết ở loại biên dịch dựa vào các hàm tạo kiểu bê tông. Đây là mức giá bạn phải trả để có một hệ thống kiểu tĩnh thực sự vững chắc.

+0

Anh ta có thể làm điều đó với mã Haskell mẫu chạy ở thời gian biên dịch – nponeccop

+0

Thật vậy, anh ta có thể, nhưng với mục đích anh ta nói rằng có vẻ hơi quá mức với tôi. –

+0

Tôi nghĩ anh ấy phải biết về tất cả các giải pháp có thể. Đây là một cơ hội tốt cho anh ta để tìm hiểu những gì TH có thể làm. @hammar là giải pháp tuyệt vời quá. – nponeccop

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