I don't really know how to properly address this since I'm new to Idris, so I'll tell my story.
I was implementing a type-safe sprintf function, with the following type signature:
sprintf : (s: String) -> typeListToFunc String (corresArgs (toPrintf (unpack s)))
Where that big pile of stuff basically looks for printf specifiers within the string and generate required arguments in term of a function. For example, "%c%f%d" would give Char -> Double -> Int -> String, and "" would simply give String.
Although this implementation works fine, it is unable to pass the tests by failing the type check. Here's a quick peek:
import Specdris.Spec
import Sprintf
specSuite : IO ()
specSuite = spec $ do
describe "Fixed tests" $ do
it "Should accept no arg when no fmt" $ do
sprintf "" `shouldBe` "" -- this is line 13
In particular, Idris could not find a match between String and typeListToFunc String (corresArgs (toPrintf (unpack ""))):
Type checking ./Sprintf.idr
Type checking ./SprintfSpec.idr
SprintfSpec.idr:10:13-24:108:
|
10 | specSuite = spec $ do
| ~~~~~~~~~ ...
When checking right hand side of specSuite with expected type
IO ()
When checking an application of function Specdris.Data.SpecResult.SpecResultDo.>>=:
Can't find implementation for Show (typeListToFunc String (corresArgs (toPrintf (unpack ""))))
Possible cause:
SprintfSpec.idr:13:18-27:When checking argument expected to function Specdris.Expectations.shouldBe:
Type mismatch between
String (Type of "")
and
typeListToFunc String (corresArgs (toPrintf (unpack ""))) (Expected type)
Specifically:
Type mismatch between
String
and
typeListToFunc String (corresArgs (toPrintf []))
As aforementioned, they are really the same type:
$ idris Sprintf.idr
*Sprintf> typeListToFunc String (corresArgs (toPrintf (unpack "")))
String : Type
Yeah, I'm really confused why couldn't Idris just get around this. FWIW I have put my source file and test spec on GitHub if anyone would like to look in details.
Turns out people came before have already realised this issue. Quote from Voile in this thread:
Add
%access public exportsolves the issue.