2015-04-01 17 views
5

Tôi đang cố gắng để thực hiện một chức năng tự động hoàn với Haskeline:kiểu biến mơ hồ với Haskeline autocompletion

import System.Console.Haskeline 
import System.Console.Haskeline.IO 
import Data.List 

mySettings :: Settings IO 
mySettings = defaultSettings { 
           historyFile = Just "myhist" 
           , complete = completeWord Nothing " \t" $ return . search 
           } 

keywords :: [String] 
keywords = ["Point","Line","Circle","Sphere"] 

search :: String -> [Completion] 
search str = map simpleCompletion $ filter (str `isPrefixOf`) keywords 

main :: IO() 
main = do 
     inputLine <- initializeInput mySettings 
     putStrLn "done" 

nhưng tôi một chút thất vọng bởi lỗi này GHC:

Ambiguous type variable `t0' in the constraint: 
    (Control.Monad.IO.Class.MonadIO t0) 
    arising from a use of `defaultSettings' 
Probable fix: add a type signature that fixes these type variable(s) 

Tôi đặt loại cho mỗi chức năng nhưng nó không giải quyết được vấn đề.

Bạn có ý tưởng về sự mơ hồ về loại này và cách xóa không?

+0

Nó thực sự là lạ.Tôi nghĩ rằng nó có một cái gì đó để làm với thực tế là các bản ghi cập nhật cần phải định hướng các loại trước khi có thể kiểm tra xem các bản cập nhật là chính xác hay không. Ở đây bạn có thể tìm thấy [SSCCE] (http://coliru.stacked-crooked.com/a/b1ea39172157a686) để có ví dụ tổng quát hơn. – Shoe

Trả lời

6

Khắc phục nhanh:

mySettings :: Settings IO 
mySettings = (defaultSettings :: Settings IO) 
    { historyFile = Just "myhist" 
    , complete = completeWord Nothing " \t" $ return . search } 

Vấn đề là một trường hợp góc cực hiếm, vì vậy không có gì ngạc nhiên khi các giải pháp trên có vẻ tùy tiện hoặc bí hiểm. Tôi cố gắng giải thích nó.

defaultSettings có loại MonadIO m => Settings m. Đó là giá trị đa hình và các giá trị như vậy thường gây ra trục trặc trong suy luận kiểu. Nói chung, chúng tôi chỉ có thể thực hiện tính toán (khớp mẫu, dự báo trường, v.v.) trên các giá trị đa hình nếu GHC có thể phỏng đoán thông số đa hình từ ngữ cảnh. Settings m có thể có nội dung hoàn toàn khác nhau tùy thuộc vào chính xác m và các phương pháp loại lớp chính xác thuộc về m.

Bây giờ, sự cố với Settings là tham số m chỉ xuất hiện trong trường complete, có loại CompletionFunc m. Nhưng trong ví dụ của chúng tôi, chúng tôi bỏ qua trường cũ complete và chỉ thay thế bằng trường mới. Do đó, theo như GHC biết, trường cũ complete có thể là bất kỳ loại nào loại nào. Và kể từ trường cũ complete là nguồn duy nhất mà từ đó chúng tôi có thể có được thông tin về thông số m của defaultSettings và chúng tôi đã để nó hoàn toàn không bị giới hạn, GHC không thể suy ra rằng mMonadIO.

Nếu chúng tôi thêm (defaultSettings :: Settings IO), thì thông số m cũ được khởi tạo đến IO và không còn vấn đề nữa. Lưu ý rằng thông số mớim hoàn toàn không liên quan đến thông số m cũ, vì chúng tôi vừa bỏ qua trường complete cũ và thay thế bằng chức năng mới. Thông số m mới được xác định là IO theo chú thích cấp cao nhất mySettings :: Settings IO.

Thực tế, chúng tôi có thể khởi tạo defaultSettings với bất kỳ loại MonadIO nào và kết quả sẽ giống nhau. Một lần nữa, điều này là do chúng tôi bỏ qua giá trị cũ của complete.

3

Loại Settings có một chút quá đa hình. Lưu ý rằng haskeline tác giả đã biết vấn đề này và cung cấp một số a setComplete function để tránh vấn đề cụ thể này. Chỉ định kiểu thủ công cũng là một tùy chọn như các câu trả lời khác hiển thị.