Tôi gặp một số bực bội một cái gì đó trong Haskell hôm nay.Lỗi loại kỳ lạ trong biểu thức Haskell cho phép - vấn đề là gì?
Đây là những gì đã xảy ra:
- tôi đã viết một hàm trong ghci và cho nó một chữ ký kiểu
- ghci phàn nàn về loại
- tôi loại bỏ các chữ ký kiểu
- ghci chấp nhận chức năng
- Tôi đã kiểm tra loại được phỏng đoán
- loại được phỏng đoán chính xác giống như loại tôi đã cố gắng cung cấp cho nó
- Tôi đã rất đau khổ
- tôi phát hiện ra rằng tôi có thể tạo lại vấn đề trong bất kỳ let-biểu
- nghiến răng; quyết định tham khảo ý kiến các chuyên gia tại SO
Cố gắng để xác định chức năng với một loại chữ ký:
Prelude Control.Monad> let myFilterM f m = do {x <- m; guard (f x); return x} :: (MonadPlus m) => (b -> Bool) -> m b -> m b
<interactive>:1:20:
Inferred type is less polymorphic than expected
Quantified type variable `b' is mentioned in the environment:
m :: (b -> Bool) -> m b -> m b (bound at <interactive>:1:16)
f :: (m b -> m b) -> Bool (bound at <interactive>:1:14)
Quantified type variable `m' is mentioned in the environment:
m :: (b -> Bool) -> m b -> m b (bound at <interactive>:1:16)
f :: (m b -> m b) -> Bool (bound at <interactive>:1:14)
In the expression:
do { x <- m;
guard (f x);
return x } ::
(MonadPlus m) => (b -> Bool) -> m b -> m b
In the definition of `myFilterM':
myFilterM f m
= do { x <- m;
guard (f x);
return x } ::
(MonadPlus m) => (b -> Bool) -> m b -> m b
Defined chức năng mà không có một loại chữ ký, kiểm tra các loại suy ra:
Prelude Control.Monad> let myFilterM f m = do {x <- m; guard (f x); return x}
Prelude Control.Monad> :t myFilterM
myFilterM :: (MonadPlus m) => (b -> Bool) -> m b -> m b
sử dụng các chức năng cho tốt tuyệt vời - nó đã làm việc đúng cách:
Prelude Control.Monad> myFilterM (>3) (Just 4)
Just 4
Prelude Control.Monad> myFilterM (>3) (Just 3)
Nothing
đoán tốt nhất của tôi như những gì đang xảy ra:
loại chú thích bằng cách nào đó không làm việc tốt với let-biểu , khi có một khối.
Đối với điểm thưởng:
có chức năng nào trong bản phân phối Haskell chuẩn thực hiện việc này không? Tôi đã rất ngạc nhiên khi filterM
thực hiện điều gì đó rất khác biệt.
Chú thích loại áp dụng cho RHS của định nghĩa, không phải là 'myFilterM', vì vậy bạn nên nói' :: (MonadPlus m) => m b'. Đây là lý do tại sao các loại 'm' và' f' trong thông báo lỗi của bạn rất lạ. Nhưng tôi vẫn nhận được thông báo lỗi "Suy ra loại ít đa hình hơn dự kiến" (mặc dù có nhiều loại hợp lý hơn) và tôi không biết nguyên nhân gây ra điều đó. – dave4420
@ dave4420 Bạn cũng sử dụng GHC 6. *? Họ mã hóa một công cụ suy luận kiểu mới trong GHC 7; có thể đó là một lỗi. – fuz
@FUZxxl Đó là với GHC 6.12.1. Tôi đã thử nó với GHC 7.0.3 và tôi nhận được hai thông báo lỗi thay vì một, không ai trong số họ đề cập đến tính đa hình. Có thể GHC 7 từ chối suy ra các kiểu đối số 'myFilterM'. – dave4420