How can I export the constructors of my data family instances? I've tried various ways without success (see commented out code):
module Test (
--Foo () (..)
--type Foo () (..)
--UnitBar
) where
class Foo a where
data Bar a :: *
instance Foo () where
data Bar () = UnitBar
The only way I've been able to successfuly export the constructor is when doing a
module Test where
Notice the absense of parentheses. The drawback of this approach is that too much information leaves!
Use
module Test (
Bar(..)
) where
to export all constructors from the associated data family Bar. Or
module Test (
Bar(UnitBar)
) where
to only export the single constructor.
You can read the relevant section in GHC's documentation for more details.
Related
I am having some trouble assigning the variables in a Python 3.6 class to a particular type--a Pathlib path. Following an example from link, I tried to create a TypeVar, but mypy is still throwing errors. I want to make sure that the class variables initialized in the __init__.py only receive a particular type at compile time. So this is just a check to make sure I don't inadvertently set a string or something else to these class variables.
Can anyone suggest the correct way to do this?
Here is some simple code.
import pathlib
from typing import Union, Dict, TypeVar, Type
Pathtype = TypeVar('Pathtype', bound=pathlib.Path)
class Request:
def __init__(self, argsdict):
self._dir_file1: Type[Pathtype] = argsdict['dir_file1']
self._dir_file2: Type[Pathtype] = argsdict['dir_file2']
The error that I am getting is:
Request.py:13: error: Invalid type "Request.Pathtype"
Request.py:14: error: Invalid type "Request.Pathtype"
Neither Type, TypeVar nor NewType are correct to use here. What you simply want to do is use Path itself:
from pathlib import Path
class Request:
def __init__(self, argsdict):
self._dir_file1: Path = argsdict['dir_file1']
self._dir_file2: Path = argsdict['dir_file2']
If you annotate your argsdict as being of type Dict[str, Path], you can skip having to annotate your fields entirely: mypy will infer the correct type:
from typing import Dict
from pathlib import Path
class Request:
def __init__(self, argsdict: Dict[str, Path]):
self._dir_file1 = argsdict['dir_file1']
self._dir_file2 = argsdict['dir_file2']
Here's a brief explanation of what the various type constructs you were attempting to use/was suggested to you actually do:
TypeVar is used when you are trying to create a generic data structure or function. For example, take List[int], which represents a list containing ints. List[...] is an example of a generic data structure: it can be parameterized by any arbitrary type.
You use TypeVar as a way of adding "parameterizable holes" if you decide you want to create your own generic data structure.
It's also possible to use TypeVars when writing generic functions. For example, suppose you want to declare that you have some function that can accept a value of any type -- but that function is guaranteed to return a value of the exact same type. You can express ideas like these using TypeVars.
The Type[...] annotation is used to indicate that some expression must be the type of a type. For example, to declare that some variable must hold an int, we would write my_var: int = 4. But what if we want to write something like my_var = int? What sort of type hint could we give that variable? In this case, we could do my_var: Type[int] = int.
NewType basically lets you "pretend" that you're taking some type and making a subclass of it -- but without requiring you to actually subclass anything at runtime. If you're careful, you can take advantage of this feature to help catch bugs where you mix different "kinds" of strings or ints or whatever -- e.g. passing in a string representing HTML into a function expecting a string representing SQL.
Replace TypeVar with NewType and remove the Type[] modifier.
I am trying the following simple function:
handler loadEntities (Key $ PersistInt64 1)
but I don't have this Key function in my scope, so I get the following error:
Not in scope: data constructor ‘Key’
Could somebody tell me what import is missing, and why it doesn't come together with scaffolding?
To create a Key from an integral type, use
toSqlKey (fromIntegral value)
Haskell beginner here, trying to wrap a HTTP REST API in a safe way and with automatic Aeson decoding of return values. I started with a Haskell function for every API call. It was a bit boilerplateish, but ok.
Looking to improve things I wanted to turn each API call into a data type of its own. For example for logging in, I would model that as Login type that specifies the method, Credentials type for method parameters and LoginReponse for the result of the API call. Parameters and response types of course have corresponding FromJSON and ToJSON instances.
For two API calls it looks something like this (using GADTs):
data Void = Void
data Credentials = Credentials {...}
data LoginResponse = LoginResponse {...}
data LogoutResponse = LogoutResponse {...}
data Command a where
Login :: Credentials -> Command LoginResponse
Logout :: Void -> Command LogoutResponse
execute :: FromJSON a => Command a -> IO a
execute cmd = do
manager <- newManager tlsManagerSettings
let request = buildHttpRequest cmd
result <- httpLbs request manager
let body = responseBody result
let parsed = fromJust $ decode body
return parsed
This works great for my use case - I can introspect Commands before executing them, I can't construct invalid API calls and Aeson knows how to decode the return values!
Only problem with this approach is that I have to keep all of my Commands in a single file under single data declaration.
I'd like to move method definitions (in my example Login and Logout) to separate modules, but to keep the execute function similar, and of course keep the type safety and Aeson decoding.
I've tried to make something using type classes, but got nowhere.
Any tips how to do that are welcome!
Since the only thing you do differently in execute for different commands is call buildHttpRequest, I propose the following alternate data type:
type Command a = Tagged a HttpRequest
(I don't know the return type of buildHttpRequest, so I made something up and assumed it returned an HttpRequest. Hopefully the idea will be clear enough even though I'm sure I got this part wrong.) The Tagged type comes from tagged, and lets you attach a type to a value; it is the urphantom type. In our case, we will use the attached type to decide how to decode JSON in the execute step.
The type of execute needs a slight modification to demand that the attached type can be decoded:
execute :: FromJSON a => Command a -> IO a
However, its implementation remains basically unchanged; simply replace buildHttpRequest with untag. These commands are not conveniently introspectable, but you will be able to split things up along module boundaries; e.g.
module FancyApp.Login (Credentials(..), LoginResponse(..), login) where
import FancyApp.Types
data Credentials = Credentials
data LoginResponse = LoginResponse
login :: Credentials -> Command LoginResponse
login = {- the old implementation of buildHttpRequest for Login -}
module FancyApp.Logout (LogoutResponse(..), logout) where
import FancyApp.Types
data LogoutResponse = LogoutResponse
logout :: Command LogoutResponse
logout = {- the old implementation of buildHttpRequest for Logout -}
I wrote some simple module in Haskell and then import it in other file. Then I'm trying to use functions with data constructors from my module — there is an error Not in scope: data constructor: <value>. How can I fix it?
Note: when I'm using it in interpreter after importing — all is good without errors.
My module Test.hs:
module Test (test_f) where
data Test_Data = T|U|F deriving (Show, Eq)
test_f x
| x == T = T
| otherwise = F
And my file file.hs:
import Test
some_func = test_f
No error if I'm writing in interpreter:
> :l Test
> test_f T
T
In interpreter I'm trying to execute some_func T, but there is an error. And how can I use class Test_Data in my file to describe annotations?
You aren't exporting it from your module:
module Test (test_f, Test_Data(..)) where
The (..) part says "export all constructors for TestData".
You have an explicit export list in your module Test:
module Test (test_f) where
The export list (test_f) states that you want to export the function test_f and nothing else. In particular, the datatype Test_Data and its constructors are hidden.
To fix this, either remove the export list like this:
module Test where
Now all things will be exported.
Or add the datatype and its constructors to the export list like this:
module Test (test_f, Test_Data(..)) where
The notation Test_Data(..) exports a datatype with all corresponding constructors.
What is going on here? I'm importing a data constructor, apparently successfully because I don't get an error, but when I try to use the constructor, I get an error saying its not in scope!
In Test.hs:
import Database.Persist (Key)
main = Key
Result:
$ ghc test.hs
[1 of 1] Compiling Main ( test.hs, test.o )
test.hs:3:8: Not in scope: data constructor `Key'
import Database.Persist (Key)
The above imports a type named Key but none of its constructors. To import the constructor Key of the type Key you need to do
import Database.Persist (Key(Key))
or just
import Database.Persist (Key(..))
to import all constructors of the given type.
In order to import a constructor you must use the following syntax
import Database.Persist (Key (..))
Generally, when importing a type or typeclass by name only the type gets imported. The constructors and member functions must be imported using the Name (..) or Name (Constructor) syntax. This is fairly convenient as it's often the case that you need to write a type signature using an imported type even if you don't ever need to construct or examine values of that type.