Mam sytuację, w której w tej chwili używam niezwykle niebezpiecznej funkcji unsafeCoerce. Na szczęście nie jest to nic ważnego, ale zastanawiałem się, czy to bezpieczne korzystanie z tej funkcji, czy też istnieje inny sposób rozwiązania tego konkretnego problemu, o którym wiedzą inni.Czy to bezpieczne korzystanie z niebezpiecznego samochodu?
Kod Mam coś jak poniżej:
data Token b = Token !Integer
identical :: Token a -> Token b -> Bool
identical (Token a) (Token b) = a == b
data F a = forall b. F (Token b) (a -> b)
retrieve :: Token b -> F a -> Maybe (a -> b)
retrieve t (F t' f) = if identical t t' then Just (unsafeCoerce f) else Nothing
Dwa dodatkowe rzeczy, aby pamiętać, jest to, że te tokeny są używane wewnątrz monady, które używam w celu zapewnienia, że dostawa liczb dla nich jest wyjątkowy (nie tworzę tego samego dwa razy). Używam również zmiennej ilościowej typu cienia, podobnie jak monady ST, aby upewnić się, że (zakładając, że użyte są tylko metody, które eksponuję w module), nie ma sposobu na zwrócenie tokena (lub w rzeczywistości nawet F) z monady bez błędu typu. Nie ujawniam również konstruktora tokena.
Myślę, że, o ile widzę, powinno to być bezpieczne korzystanie z niebezpiecznego samochodu, ponieważ mogę powiedzieć z (mam nadzieję) dość wysokim przekonaniem, że wartość, którą wymuszam, jest w rzeczywistości dokładnie taka, wymuszam to, ale mogę się mylić. Próbowałem również przy użyciu Data.Typeable, który działa ładnie, ale w tej chwili próbuję tego uniknąć ograniczenia Typeable, zwłaszcza, że gcast wydaje się robić coś na wiele sposobów podobne, i nadal potrzebowałbym tokenów, aby rozróżnić między różne F tego samego typu.
Dziękuję bardzo za pomoc/radę.
Wygląda to trochę jak 'Data.Typeable', który używa' unsafeCoerce' pod kołdrą do implementacji 'cast'. –
Jest to bardzo podobne - w rzeczywistości Iirc powiedziałem tak samo w drugiej części ostatniego akapitu pytania. Dzięki i tak. – DarkOtter
Jeśli skutecznie kopiujesz 'cast', użycie' unsafeCoerce' jest bezpieczne, ale tracisz wygenerowany kompilator 'typeOf' /' TypeRep'. Możesz rozważyć użycie 'TypeRep' zamiast' Integer' w tokenie. –