Piszę Haskella już od jakiegoś czasu, ale chciałem spróbować eksperymentów z językiem Idris i uzależnienia od pisania. Zagrałem trochę i przeczytałem podstawowy dokument, ale chcę wyrazić pewien styl funkcji i nie wiem jak/jeśli to możliwe.Ograniczenia pisania zależnego w Idrisie
Oto kilka przykładów tego, co chcę wiedzieć, czy nie można wyrazić:
pierwszy: funkcja, która zajmuje dwie liczby naturalne, ale tylko wpisać czeki, jeśli pierwszy jest mniejszy niż drugi. Tak więc f : Nat -> Nat -> whatever
gdzie nat1 jest mniejsze niż nat2. Chodzi o to, że gdyby zadzwonił jak f 5 10
, to by zadziałało, ale jeśli nazwałbym to jak f 10 5
, nie dałoby się sprawdzić.
sekunda: funkcja, która pobiera ciąg znaków i listę napisów, które są wpisywane, sprawdza tylko, czy pierwszy ciąg znaków znajduje się na liście ciągów znaków.
Czy takie funkcje są możliwe w Idris? Jeśli tak, to jak zaimplementować jeden z prostych przykładów? Dzięki!
EDIT:
Z pomocą kilku użytkowników następujące funkcje rozwiązanie zostało napisane:
module Main
import Data.So
f : (n : Nat) -> (m : Nat) -> {auto isLT : So (n < m)} -> Int
f _ _ = 50
g : (x : String) -> (xs : List String) -> {auto inIt : So (elem x xs)} -> Int
g x xs = 52
main : IO()
main = putStrLn $ show $ g "hai" ["test", "yo", "ban", "hai", "dog"]
te obecne rozwiązania nie działają dla dużych sprawach. Na przykład, jeśli uruchamiasz f z liczbami powyżej kilku tysięcy, trwa to zawsze (nie dosłownie). Myślę, że dzieje się tak dlatego, że sprawdzanie typu jest obecnie oparte na wyszukiwaniu. Jeden z użytkowników skomentował, że możliwe jest podanie podpowiedzi na auto poprzez samodzielne napisanie dowodu. Zakładając, że jest to potrzebne, jak można by napisać taki dowód na jeden z tych prostych przypadków?
Nie jestem zbyt zaznajomiony z Idrisem, ale jest to z pewnością możliwe. Rzuciłem szybkie spojrzenie na [stdlib] (https://github.com/idris-lang/Idris-dev/tree/master/libs/prelude/Prelude) - pierwsze byłoby coś w stylu 'f: (nm: Nat) -> {isLT: Prelude.Nat.LT nm} -> X' i drugi 'g: (x: String) (xs: List String) -> {in: Prelude.List.elem x xs = True} -> Y'. (gdzie '=' jest równością propozycyjną, nie jest pewny, czy symbol Idrys używa do tego?) Możliwe są inne, lepsze kodowania, ale te działają tylko z stdlib. – user2407038
@ user2407038, [it's] (http://docs.idris-lang.org/en/latest/tutorial/miscellany.html) '{auto isLT: Prelude.Nat.LT nm}' and '{auto in: Prelude .List.elem x xs = True} '. – user3237465
To jest wspaniałe @ user2407038 Zauważam, że kiedy robię "' 'f 50 100''' wszystko jest w porządku. Ale kiedy robię '' 'f 500 1000''', stwierdza on, że nie może znaleźć rozwiązania. Zakładam, że to dlatego, że brutalnie coś zmusza? Czy istnieje sposób na uzyskanie tego samego wyniku, który chcę, aby działał dla większych liczb? –