Tôi đã cố gắng triển khai chức năng filterM bằng cách sử dụng foldr, nhưng nhận được lỗi mà tôi không thể hiểu tại sao.Tôi không thể hiểu tại sao Haskell không thể suy ra loại này
thực hiện của tôi (Người ta chỉ cho sự hiểu biết, tôi biết tôi nên sử dụng làm ký hiệu ...):
filterM :: (Monad m) => (a -> (m Bool)) -> [a] -> m [a]
filterM f list = foldr foldFn (return []) list
where
foldFn :: (Monad m) => a -> m [a] -> m [a]
foldFn x acc = let
m = f x
in acc >>=
\l -> m >>=
\b -> (if b == True then return (x:l) else return l)
Tôi Lấy lỗi sau
Could not deduce (a ~ a1)
from the context (Monad m)
bound by the type signature for
filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
at wadler.hs:124:12-55
or from (Monad m1)
bound by the type signature for
ff :: Monad m1 => a1 -> m1 [a1] -> m1 [a1]
at wadler.hs:127:23-54
`a' is a rigid type variable bound by
the type signature for
filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
at wadler.hs:124:12
`a1' is a rigid type variable bound by
the type signature for ff :: Monad m1 => a1 -> m1 [a1] -> m1 [a1]
at wadler.hs:127:23
In the first argument of `f', namely `x'
In the expression: f x
In an equation for `m': m = f x
Tôi không hiểu tại sao loại không thể được suy luận vì foldr có loại foldr :: (a -> b -> b) -> b -> [a] -> b
Cảm ơn trước, Alex
Bạn có chắc chắn đây là mã đúng không? Tôi không có 'xs' trong phạm vi. – bheklilr
Bạn không nên thêm chữ ký kiểu vào hàm cục bộ nếu bạn đang sử dụng các biến được giới thiệu bởi các mẫu bên ngoài. Nếu bạn muốn làm điều đó, bạn * phải * sử dụng phần mở rộng 'ScopedTypeVariables' và định lượng qua các biến trong chữ ký ngoài. – Bakuriu